home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume26 / veos-2.0 / part08 < prev    next >
Encoding:
Text File  |  1993-04-25  |  74.9 KB  |  2,937 lines

  1. Newsgroups: comp.sources.unix
  2. From: voodoo@hitl.washington.edu (Geoffery Coco)
  3. Subject: v26i191: veos-2.0 - The Virtual Environment Operating Shell, V2.0, Part08/16
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: voodoo@hitl.washington.edu (Geoffery Coco)
  8. Posting-Number: Volume 26, Issue 191
  9. Archive-Name: veos-2.0/part08
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 8 (of 16)."
  18. # Contents:  kernel_private/src/nancy/nancy_match.c
  19. #   src/kernel_current/nancy/nancy_match.c
  20. #   src/kernel_current/talk/socket.c src/xlisp/xcore/c/xldmem.c
  21. # Wrapped by vixie@efficacy.home.vix.com on Sun Apr 25 23:10:40 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'kernel_private/src/nancy/nancy_match.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'kernel_private/src/nancy/nancy_match.c'\"
  25. else
  26. echo shar: Extracting \"'kernel_private/src/nancy/nancy_match.c'\" \(17745 characters\)
  27. sed "s/^X//" >'kernel_private/src/nancy/nancy_match.c' <<'END_OF_FILE'
  28. X/****************************************************************************************
  29. X *                                            *
  30. X * file: nancy_match.c                                    *
  31. X *                                            *
  32. X * February 15, 1992:  Matching semantics for grouples.                           *
  33. X *                                            *
  34. X * by Geoffrey P. Coco at the HITLab, Seattle.                          *
  35. X *                                            *
  36. X ****************************************************************************************/
  37. X
  38. X/****************************************************************************************
  39. X * Copyright (C) 1992  Geoffrey P. Coco, Human Interface Technology Lab, Seattle    *
  40. X ****************************************************************************************/
  41. X
  42. X
  43. X/****************************************************************************************
  44. X *                          includes galore                    */
  45. X
  46. X#include "kernel.h"
  47. X#include <malloc.h>
  48. X#include <varargs.h>
  49. X
  50. X/****************************************************************************************/
  51. X
  52. X
  53. X
  54. X/****************************************************************************************
  55. X * Nancy_MatchGrouple                                    */
  56. X
  57. XTVeosErr Nancy_MatchGrouple(pMatchSpec)
  58. X    TPMatchRec        pMatchSpec;
  59. X{
  60. X    TVeosErr         iErr;
  61. X
  62. X    if (TESTFLAG(NANCY_ContentMask, pMatchSpec->pPatGr->iFlags))
  63. X    iErr = Nancy_MatchContentGrouple(pMatchSpec);
  64. X    else
  65. X    iErr = Nancy_MatchPositionGrouple(pMatchSpec);
  66. X
  67. X    return(iErr);
  68. X
  69. X    } /* Nancy_MatchGrouple */
  70. X/****************************************************************************************/
  71. X
  72. X
  73. X
  74. X/****************************************************************************************
  75. X *                       private routines                    *
  76. X ****************************************************************************************/
  77. X
  78. X
  79. X/****************************************************************************************
  80. X * Nancy_MatchPositionGrouple                                */
  81. X
  82. XTVeosErr Nancy_MatchPositionGrouple(pMatchSpec)
  83. X    TPMatchRec        pMatchSpec;
  84. X{
  85. X    int            iPatElts, iSrcElts;
  86. X    int            iMoreSrcElts;
  87. X    TPElt        pPatFinger, pSrcFinger;
  88. X    TPGrouple        pPatGr, pSrcGr;
  89. X    int            iPatIndex, iSrcIndex;
  90. X
  91. X    boolean        bMarked, bTouched;
  92. X    boolean        bMarkWithin, bTouchWithin;
  93. X    TPReplaceRec    pMarkPB = nil, pTouchPB = nil;
  94. X    TVeosErr        iErr = VEOS_SUCCESS;
  95. X
  96. X    /** setup cached locals **/
  97. X
  98. X    pPatGr = pMatchSpec->pPatGr;
  99. X    pSrcGr = pMatchSpec->pSrcGr;
  100. X    iSrcElts = pSrcGr->iElts;
  101. X    iPatElts = pPatGr->iElts;
  102. X
  103. X    bMarkWithin = TESTFLAG(NANCY_MarkWithinMask, pPatGr->iFlags);
  104. X    bTouchWithin = TESTFLAG(NANCY_TouchWithinMask, pPatGr->iFlags);
  105. X
  106. X
  107. X    /** setup replace and touch descriptors to pass back.
  108. X     **/
  109. X
  110. X    if (bMarkWithin) {
  111. X    Nancy_NewReplaceNode(&pMarkPB);
  112. X    pMarkPB->pEnviron = pSrcGr;
  113. X    }
  114. X    if (bTouchWithin) {
  115. X    Nancy_NewReplaceNode(&pTouchPB);
  116. X    pTouchPB->pEnviron = pSrcGr;
  117. X    }
  118. X
  119. X
  120. X    /** pattern controls the flow 
  121. X     ** loop through each pattern element until...
  122. X     ** - an element match fails, or
  123. X     ** - we run out of src elements (pattern too big)
  124. X     ** - we run out of pattern elements (pattern not sufficient)
  125. X     **/
  126. X
  127. X    iSrcIndex = 0;
  128. X    iPatIndex = 0;
  129. X
  130. X    while (iErr == VEOS_SUCCESS) {    
  131. X
  132. X    /*******************************************************
  133. X     ** first, pass the gauntlet of tests for continuance **
  134. X     *******************************************************/
  135. X
  136. X    /** check for end of pattern **/
  137. X
  138. X    if (iPatIndex >= iPatElts) {
  139. X        if (iSrcIndex != iSrcElts)
  140. X        iErr = NANCY_PatTooShort;
  141. X        break;
  142. X        }
  143. X
  144. X
  145. X    /** setup local info of current pattern element **/
  146. X
  147. X    pPatFinger = &pPatGr->pEltList[iPatIndex];
  148. X    pSrcFinger = &pSrcGr->pEltList[iSrcIndex];
  149. X
  150. X    bMarked = TESTFLAG(NANCY_EltMarkMask, pPatFinger->iFlags);
  151. X    bTouched = TESTFLAG(NANCY_EltTouchMask, pPatFinger->iFlags);
  152. X
  153. X
  154. X    /** check for end of source,
  155. X     ** and not about to insert,
  156. X     ** and matching zero or more.
  157. X     **/
  158. X
  159. X    if (iSrcIndex >= iSrcElts &&
  160. X        pPatFinger->iType != GR_here &&
  161. X        pPatFinger->iType != GR_theseall) {
  162. X
  163. X        /** must be more pattern elts, or would not have got this far **/
  164. X
  165. X        iErr = NANCY_SrcTooShort;
  166. X        break;
  167. X        }
  168. X    
  169. X
  170. X    /**********************************************
  171. X     ** second, perform the element match itself **
  172. X     **********************************************/
  173. X
  174. X    switch (pPatFinger->iType) {
  175. X        
  176. X    case GR_theseall:
  177. X        if (iSrcIndex < iSrcElts) {
  178. X        if (bMarked) {
  179. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  180. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcElts - 1;
  181. X            pMarkPB->iZones ++;
  182. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  183. X            pMarkPB->iInsertElt = iSrcIndex;
  184. X            }
  185. X        else if (bTouched) {
  186. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  187. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcElts - 1;
  188. X            pTouchPB->iZones ++;
  189. X            }
  190. X        iSrcIndex = iSrcElts;
  191. X        }
  192. X        iSrcIndex = iSrcIndex - 1;
  193. X        break;
  194. X
  195. X    case GR_here:
  196. X        pMarkPB->iInsertElt = iSrcIndex;
  197. X        iSrcIndex = iSrcIndex - 1;
  198. X        break;
  199. X    
  200. X    case GR_these:
  201. X        iMoreSrcElts = pPatFinger->u.iVal - 1;
  202. X
  203. X        if (iSrcIndex + iMoreSrcElts >= iSrcElts)
  204. X        iErr = NANCY_SrcTooShort;
  205. X
  206. X        else {
  207. X        if (bMarked) {
  208. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  209. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex + iMoreSrcElts;
  210. X            pMarkPB->iZones ++;
  211. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  212. X            pMarkPB->iInsertElt = iSrcIndex;
  213. X            }
  214. X        else if (bTouched) {
  215. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  216. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight =
  217. X            iSrcIndex + iMoreSrcElts;
  218. X            pTouchPB->iZones ++;
  219. X            }
  220. X        iSrcIndex += iMoreSrcElts;
  221. X        }
  222. X        break;
  223. X
  224. X    case GR_grouple:
  225. X    case GR_vector:
  226. X        if (pPatFinger->iType != pSrcFinger->iType)
  227. X        iErr = NANCY_NoMatch;
  228. X
  229. X        else {
  230. X        pMatchSpec->pSrcGr = pSrcFinger->u.pGr;
  231. X        pMatchSpec->pPatGr = pPatFinger->u.pGr;
  232. X        
  233. X        iErr = Nancy_MatchGrouple(pMatchSpec);
  234. X        
  235. X        pMatchSpec->pSrcGr = pSrcGr;
  236. X        pMatchSpec->pPatGr = pPatGr;
  237. X        
  238. X        if (iErr == VEOS_SUCCESS) {
  239. X            if (bMarked) {
  240. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  241. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  242. X            pMarkPB->iZones ++;
  243. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  244. X                pMarkPB->iInsertElt = iSrcIndex;
  245. X            }
  246. X            else if (bTouched) {
  247. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  248. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  249. X            pTouchPB->iZones ++;
  250. X            }
  251. X            }
  252. X        }
  253. X        break;
  254. X
  255. X    default:
  256. X        iErr = Nancy_EltIdentical(pPatFinger, pSrcFinger);
  257. X        if (iErr == VEOS_SUCCESS) {
  258. X        if (bMarked) {
  259. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  260. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  261. X            pMarkPB->iZones ++;
  262. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  263. X            pMarkPB->iInsertElt = iSrcIndex;
  264. X            }
  265. X        else if (bTouched) {
  266. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  267. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  268. X            pTouchPB->iZones ++;
  269. X            }
  270. X        }
  271. X        break;
  272. X
  273. X        } /* switch */
  274. X
  275. X    iPatIndex ++;
  276. X    iSrcIndex ++;
  277. X    }
  278. X
  279. X    /********************
  280. X     ** third, cleanup **
  281. X     ********************/
  282. X    
  283. X    if (iErr != VEOS_SUCCESS) {
  284. X
  285. X    if (bMarkWithin)
  286. X        Nancy_DisposeReplaceNode(pMarkPB);
  287. X    if (bTouchWithin)
  288. X        Nancy_DisposeReplaceNode(pTouchPB);
  289. X    }
  290. X    else {
  291. X    if (bMarkWithin) {
  292. X        pMarkPB->pNext = pMatchSpec->pReplaceList;
  293. X        pMatchSpec->pReplaceList = pMarkPB;
  294. X        }
  295. X    if (bTouchWithin) {
  296. X        pTouchPB->pNext = pMatchSpec->pTouchList;
  297. X        pMatchSpec->pTouchList = pTouchPB;
  298. X        }
  299. X    }
  300. X    
  301. X    return(iErr);
  302. X
  303. X    } /* MatchPositionGrouple */
  304. X/****************************************************************************************/
  305. X
  306. X
  307. X
  308. X/****************************************************************************************
  309. X * Nancy_MatchContentGrouple                                */
  310. X
  311. XTVeosErr Nancy_MatchContentGrouple(pMatchSpec)
  312. X    TPMatchRec        pMatchSpec;
  313. X{
  314. X    int            iPatElts;
  315. X    int            iPatIndex;
  316. X    TPElt        pWildElt, pPatElt;
  317. X    TPGrouple        pPatGr;
  318. X
  319. X    boolean        bMarkWithin, bTouchWithin;
  320. X    TPReplaceRec    pMarkPB = nil, pTouchPB = nil;
  321. X    TVeosErr        iErr = VEOS_SUCCESS;
  322. X
  323. X
  324. X    pPatGr = pMatchSpec->pPatGr;
  325. X    iPatElts = pPatGr->iElts;
  326. X
  327. X
  328. X    /** content addressable grouples are specified
  329. X     ** very precisely.  ie, there must be at least
  330. X     ** one element, and the last element must be a * form.
  331. X     **
  332. X     ** thus, if a pattern came this far...
  333. X     ** it better have a * element in last location.
  334. X     ** so, the last elt type must be GR_any or GR_some.
  335. X     **/
  336. X
  337. X    pWildElt = &pPatGr->pEltList[iPatElts - 1];
  338. X
  339. X
  340. X    /** don't match normally against * form **/
  341. X    iPatElts --;
  342. X
  343. X    
  344. X    bMarkWithin = TESTFLAG(NANCY_MarkWithinMask, pPatGr->iFlags);
  345. X    bTouchWithin = TESTFLAG(NANCY_TouchWithinMask, pPatGr->iFlags);
  346. X
  347. X    /** setup replace descriptor to pass back.
  348. X     ** note, many descriptors can be created with one match...
  349. X     ** for example, when the caller calls this function again
  350. X     ** during a 'MatchMany' type match.
  351. X     **/
  352. X    
  353. X    if (bMarkWithin) {
  354. X    Nancy_NewReplaceNode(&pMarkPB);
  355. X    pMarkPB->pEnviron = pMatchSpec->pSrcGr;
  356. X    }
  357. X    if (bTouchWithin) {
  358. X    Nancy_NewReplaceNode(&pTouchPB);
  359. X    pTouchPB->pEnviron = pMatchSpec->pSrcGr;
  360. X    }
  361. X    
  362. X    
  363. X    /** pattern controls the flow 
  364. X     ** loop through each pattern element until...
  365. X     ** - an element match fails, or
  366. X     ** - we run out of pattern elements (match successful)
  367. X     **/
  368. X    
  369. X    for (iPatIndex = 0, pPatElt = pMatchSpec->pPatGr->pEltList;
  370. X     iErr == VEOS_SUCCESS;
  371. X     iPatIndex ++, pPatElt ++) {
  372. X    
  373. X    
  374. X    /** check for end of pattern **/
  375. X    
  376. X    if (iPatIndex >= iPatElts)
  377. X        break;
  378. X    
  379. X    /** void matches instantly, no match necessary **/
  380. X
  381. X    if (pPatElt->iType == GR_here)
  382. X        pMarkPB->iInsertElt = 0;
  383. X
  384. X    /** match pattern element against each elt in src grouple **/
  385. X
  386. X    else 
  387. X        iErr = Nancy_MapMatch(pMatchSpec, iPatIndex, pMarkPB, pTouchPB);
  388. X
  389. X    } /* pattern element loop */
  390. X
  391. X
  392. X
  393. X    Nancy_MapRestore(pMatchSpec,
  394. X             ((TESTFLAG(NANCY_EltMarkMask, pWildElt->iFlags) &&
  395. X               iErr == VEOS_SUCCESS) ? TRUE : FALSE),
  396. X             ((TESTFLAG(NANCY_EltTouchMask, pWildElt->iFlags) &&
  397. X               iErr == VEOS_SUCCESS) ? TRUE : FALSE),
  398. X             pMarkPB, pTouchPB);
  399. X    
  400. X
  401. X
  402. X    /** cleanup **/
  403. X    
  404. X    if (iErr != VEOS_SUCCESS) {
  405. X
  406. X    if (bMarkWithin)
  407. X        Nancy_DisposeReplaceNode(pMarkPB);
  408. X    if (bTouchWithin)
  409. X        Nancy_DisposeReplaceNode(pTouchPB);
  410. X    }
  411. X    else {
  412. X    if (bMarkWithin) {
  413. X        pMarkPB->pNext = pMatchSpec->pReplaceList;
  414. X        pMatchSpec->pReplaceList = pMarkPB;
  415. X        }
  416. X    if (bTouchWithin) {
  417. X        pTouchPB->pNext = pMatchSpec->pTouchList;
  418. X        pMatchSpec->pTouchList = pTouchPB;
  419. X        }
  420. X    }
  421. X
  422. X    return(iErr);
  423. X
  424. X    } /* MatchContentGrouple */
  425. X/****************************************************************************************/
  426. X
  427. X
  428. X
  429. X/****************************************************************************************/
  430. XTVeosErr Nancy_MapMatch(pMatchSpec, iPatIndex, pMarkPB, pTouchPB)
  431. X    TPMatchRec        pMatchSpec;
  432. X    int            iPatIndex;
  433. X    TPReplaceRec    pMarkPB, pTouchPB;
  434. X{
  435. X    int            iSrcElts, iSrcIndex;
  436. X    TPElt        pSrcFinger, pPatElt;
  437. X    TPGrouple        pSrcGr, pPatGr;
  438. X    int            iMatches;
  439. X    boolean        bPatMarked, bPatTouched;
  440. X    TVeosErr        iErr = VEOS_SUCCESS;
  441. X    
  442. X    
  443. X    pSrcGr = pMatchSpec->pSrcGr;
  444. X    iSrcElts = pSrcGr->iElts;
  445. X    
  446. X    pPatGr = pMatchSpec->pPatGr;
  447. X    pPatElt = &pPatGr->pEltList[iPatIndex];
  448. X    
  449. X    bPatMarked = TESTFLAG(NANCY_EltMarkMask, pPatElt->iFlags);
  450. X    bPatTouched = TESTFLAG(NANCY_EltTouchMask, pPatElt->iFlags);
  451. X    
  452. X#ifndef OPTIMAL
  453. X    if (NANCY_BUGS) {
  454. X    fprintf(stderr, "matching:  ");
  455. X    Nancy_ElementToStream(pPatElt, stderr);
  456. X    fprintf(stderr, "against:  ");
  457. X    Nancy_GroupleToStream(pSrcGr, stderr);
  458. X    }
  459. X#endif
  460. X    
  461. X    /** perform exhaustive search for pat
  462. X     ** element through the source grouple.
  463. X     **/
  464. X    iMatches = 0;
  465. X    
  466. X    switch (pPatElt->iType) {
  467. X
  468. X    case GR_grouple:
  469. X    case GR_vector:
  470. X    for (iSrcIndex = 0, pSrcFinger = pSrcGr->pEltList;
  471. X         iSrcIndex < iSrcElts;
  472. X         iSrcIndex ++, pSrcFinger ++) {
  473. X        
  474. X        if (pPatElt->iType == pSrcFinger->iType) {
  475. X        
  476. X        pMatchSpec->pSrcGr = pSrcFinger->u.pGr;
  477. X        pMatchSpec->pPatGr = pPatElt->u.pGr;
  478. X        
  479. X        iErr = Nancy_MatchGrouple(pMatchSpec);
  480. X        
  481. X        pMatchSpec->pSrcGr = pSrcGr;
  482. X        pMatchSpec->pPatGr = pPatGr;
  483. X        
  484. X        if (iErr == VEOS_SUCCESS) {
  485. X            
  486. X            if (bPatMarked) {
  487. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  488. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  489. X            pMarkPB->iZones ++;
  490. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  491. X                pMarkPB->iInsertElt = iSrcIndex;
  492. X            }
  493. X            else if (bPatTouched) {
  494. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  495. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  496. X            pTouchPB->iZones ++;
  497. X            }
  498. X            
  499. X            iMatches ++;
  500. X
  501. X            if (NANCY_BUGS) {
  502. X            fprintf(stderr, "matched on:    ");
  503. X            Nancy_ElementToStream(pSrcFinger, stderr);
  504. X            }            
  505. X
  506. X            /** mark src element as having been matched **/
  507. X            SETFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  508. X            
  509. X            if (pMatchSpec->iFreqFlag == NANCY_MatchOne)
  510. X            break;
  511. X            
  512. X            } /* matched */
  513. X        } /* same type */
  514. X        } /* for */
  515. X    break;
  516. X
  517. X    default:
  518. X    for (iSrcIndex = 0, pSrcFinger = pSrcGr->pEltList;
  519. X         iSrcIndex < iSrcElts;
  520. X         iSrcIndex ++, pSrcFinger ++) {
  521. X        
  522. X        if (pPatElt->iType == pSrcFinger->iType &&
  523. X        Nancy_EltIdentical(pPatElt, pSrcFinger) == VEOS_SUCCESS) {
  524. X        
  525. X        if (bPatMarked) {
  526. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  527. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  528. X            pMarkPB->iZones ++;
  529. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  530. X            pMarkPB->iInsertElt = iSrcIndex;
  531. X            }
  532. X        else if (bPatTouched) {
  533. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  534. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  535. X            pTouchPB->iZones ++;
  536. X            }
  537. X        
  538. X        iMatches ++;
  539. X
  540. X        if (NANCY_BUGS) {
  541. X            fprintf(stderr, "matched on:    ");
  542. X            Nancy_ElementToStream(pSrcFinger, stderr);
  543. X            }
  544. X
  545. X        /** mark src element as having been matched **/
  546. X        SETFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  547. X        
  548. X        if (pMatchSpec->iFreqFlag == NANCY_MatchOne)
  549. X            break;
  550. X        
  551. X        } /* matched */
  552. X        } /* for */
  553. X    break;
  554. X
  555. X    } /* switch */
  556. X    
  557. X    if (iMatches == 0)
  558. X    iErr = NANCY_NoMatch;
  559. X    else
  560. X    iErr = VEOS_SUCCESS;
  561. X    
  562. X    return(iErr);
  563. X    
  564. X    } /* Nancy_MapMatch */
  565. X/****************************************************************************************/
  566. X
  567. X
  568. X
  569. X/****************************************************************************************/
  570. XTVeosErr Nancy_MapRestore(pMatchSpec, bGatherUnmatched, bTouchUnmatched, pMarkPB, pTouchPB)
  571. X    TPMatchRec        pMatchSpec;
  572. X    boolean        bGatherUnmatched, bTouchUnmatched;
  573. X    TPReplaceRec    pMarkPB, pTouchPB;
  574. X{
  575. X    int            iSrcIndex, iSrcElts;
  576. X    TPElt        pSrcFinger;
  577. X    TVeosErr        iErr = VEOS_SUCCESS;
  578. X    
  579. X    iSrcElts = pMatchSpec->pSrcGr->iElts;
  580. X
  581. X    if (bGatherUnmatched) {
  582. X
  583. X    for (iSrcIndex = 0, pSrcFinger = pMatchSpec->pSrcGr->pEltList;
  584. X         iSrcIndex < iSrcElts; 
  585. X         iSrcIndex ++, pSrcFinger ++) {
  586. X
  587. X        if (TESTFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags)) {
  588. X        
  589. X        /** clear the source marks **/
  590. X        CLRFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  591. X        }
  592. X        
  593. X        else {
  594. X        /** gather unmatched elements into replace list **/
  595. X        
  596. X        if (pMarkPB->pWipeList[pMarkPB->iZones - 1].iRight == (iSrcIndex - 1))
  597. X            pMarkPB->pWipeList[pMarkPB->iZones - 1].iRight = iSrcIndex;
  598. X        else {
  599. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  600. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  601. X            pMarkPB->iZones ++;
  602. X            }
  603. X        }
  604. X        } /* for */
  605. X    } /* gather marked */
  606. X
  607. X    else if (bTouchUnmatched) {
  608. X
  609. X    for (iSrcIndex = 0, pSrcFinger = pMatchSpec->pSrcGr->pEltList;
  610. X         iSrcIndex < iSrcElts; 
  611. X         iSrcIndex ++, pSrcFinger ++) {
  612. X
  613. X        if (TESTFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags)) {
  614. X        
  615. X        /** clear the source marks **/
  616. X        CLRFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  617. X        }
  618. X        
  619. X        else {
  620. X        /** gather unmatched elements into touch list **/
  621. X        
  622. X        if (pTouchPB->pWipeList[pTouchPB->iZones - 1].iRight == (iSrcIndex - 1))
  623. X            pTouchPB->pWipeList[pTouchPB->iZones - 1].iRight = iSrcIndex;
  624. X        else {
  625. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  626. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  627. X            pTouchPB->iZones ++;
  628. X            }
  629. X        }
  630. X        } /* for */
  631. X    } /* gather touch */
  632. X
  633. X    return(iErr);
  634. X
  635. X    } /* Nancy_MapRestore */
  636. X/****************************************************************************************
  637. X
  638. X
  639. X
  640. X/****************************************************************************************
  641. X * Nancy_NewReplaceNode                                    */
  642. X
  643. XTVeosErr Nancy_NewReplaceNode(hNode)
  644. X    THReplaceRec    hNode;
  645. X{
  646. X    TVeosErr         iErr;
  647. X    TPReplaceRec    pNode;
  648. X
  649. X    iErr = Shell_NewBlock(sizeof(TReplaceRec), &pNode, "replace-bp");
  650. X    if (iErr == VEOS_SUCCESS) {
  651. X    pNode->pEnviron = nil;
  652. X    pNode->iZones = 0;
  653. X    pNode->iInsertElt = -1;
  654. X    pNode->pNext = nil;
  655. X    }
  656. X
  657. X    *hNode = pNode;
  658. X
  659. X    return(iErr);
  660. X
  661. X    } /* Nancy_NewReplaceNode */
  662. X/****************************************************************************************/
  663. X
  664. X
  665. X
  666. X/****************************************************************************************
  667. X * Nancy_DisposeReplaceNode                                */
  668. X
  669. XTVeosErr Nancy_DisposeReplaceNode(pNode)
  670. X    TPReplaceRec    pNode;
  671. X{
  672. X    TVeosErr         iErr;
  673. X
  674. X    iErr = Shell_ReturnBlock(pNode, sizeof(TReplaceRec), "replace-bp");
  675. X
  676. X    return(iErr);
  677. X
  678. X    } /* Nancy_DisposeReplaceNode */
  679. X/****************************************************************************************/
  680. X
  681. X
  682. X
  683. X/****************************************************************************************
  684. X * Nancy_                                        */
  685. X
  686. XTVeosErr Nancy_()
  687. X{
  688. X    TVeosErr         iErr;
  689. X
  690. X
  691. X    return(iErr);
  692. X
  693. X    } /* Nancy_ */
  694. X/****************************************************************************************/
  695. X
  696. END_OF_FILE
  697. if test 17745 -ne `wc -c <'kernel_private/src/nancy/nancy_match.c'`; then
  698.     echo shar: \"'kernel_private/src/nancy/nancy_match.c'\" unpacked with wrong size!
  699. fi
  700. # end of 'kernel_private/src/nancy/nancy_match.c'
  701. fi
  702. if test -f 'src/kernel_current/nancy/nancy_match.c' -a "${1}" != "-c" ; then 
  703.   echo shar: Will not clobber existing file \"'src/kernel_current/nancy/nancy_match.c'\"
  704. else
  705. echo shar: Extracting \"'src/kernel_current/nancy/nancy_match.c'\" \(17745 characters\)
  706. sed "s/^X//" >'src/kernel_current/nancy/nancy_match.c' <<'END_OF_FILE'
  707. X/****************************************************************************************
  708. X *                                            *
  709. X * file: nancy_match.c                                    *
  710. X *                                            *
  711. X * February 15, 1992:  Matching semantics for grouples.                           *
  712. X *                                            *
  713. X * by Geoffrey P. Coco at the HITLab, Seattle.                          *
  714. X *                                            *
  715. X ****************************************************************************************/
  716. X
  717. X/****************************************************************************************
  718. X * Copyright (C) 1992  Geoffrey P. Coco, Human Interface Technology Lab, Seattle    *
  719. X ****************************************************************************************/
  720. X
  721. X
  722. X/****************************************************************************************
  723. X *                          includes galore                    */
  724. X
  725. X#include "kernel.h"
  726. X#include <malloc.h>
  727. X#include <varargs.h>
  728. X
  729. X/****************************************************************************************/
  730. X
  731. X
  732. X
  733. X/****************************************************************************************
  734. X * Nancy_MatchGrouple                                    */
  735. X
  736. XTVeosErr Nancy_MatchGrouple(pMatchSpec)
  737. X    TPMatchRec        pMatchSpec;
  738. X{
  739. X    TVeosErr         iErr;
  740. X
  741. X    if (TESTFLAG(NANCY_ContentMask, pMatchSpec->pPatGr->iFlags))
  742. X    iErr = Nancy_MatchContentGrouple(pMatchSpec);
  743. X    else
  744. X    iErr = Nancy_MatchPositionGrouple(pMatchSpec);
  745. X
  746. X    return(iErr);
  747. X
  748. X    } /* Nancy_MatchGrouple */
  749. X/****************************************************************************************/
  750. X
  751. X
  752. X
  753. X/****************************************************************************************
  754. X *                       private routines                    *
  755. X ****************************************************************************************/
  756. X
  757. X
  758. X/****************************************************************************************
  759. X * Nancy_MatchPositionGrouple                                */
  760. X
  761. XTVeosErr Nancy_MatchPositionGrouple(pMatchSpec)
  762. X    TPMatchRec        pMatchSpec;
  763. X{
  764. X    int            iPatElts, iSrcElts;
  765. X    int            iMoreSrcElts;
  766. X    TPElt        pPatFinger, pSrcFinger;
  767. X    TPGrouple        pPatGr, pSrcGr;
  768. X    int            iPatIndex, iSrcIndex;
  769. X
  770. X    boolean        bMarked, bTouched;
  771. X    boolean        bMarkWithin, bTouchWithin;
  772. X    TPReplaceRec    pMarkPB = nil, pTouchPB = nil;
  773. X    TVeosErr        iErr = VEOS_SUCCESS;
  774. X
  775. X    /** setup cached locals **/
  776. X
  777. X    pPatGr = pMatchSpec->pPatGr;
  778. X    pSrcGr = pMatchSpec->pSrcGr;
  779. X    iSrcElts = pSrcGr->iElts;
  780. X    iPatElts = pPatGr->iElts;
  781. X
  782. X    bMarkWithin = TESTFLAG(NANCY_MarkWithinMask, pPatGr->iFlags);
  783. X    bTouchWithin = TESTFLAG(NANCY_TouchWithinMask, pPatGr->iFlags);
  784. X
  785. X
  786. X    /** setup replace and touch descriptors to pass back.
  787. X     **/
  788. X
  789. X    if (bMarkWithin) {
  790. X    Nancy_NewReplaceNode(&pMarkPB);
  791. X    pMarkPB->pEnviron = pSrcGr;
  792. X    }
  793. X    if (bTouchWithin) {
  794. X    Nancy_NewReplaceNode(&pTouchPB);
  795. X    pTouchPB->pEnviron = pSrcGr;
  796. X    }
  797. X
  798. X
  799. X    /** pattern controls the flow 
  800. X     ** loop through each pattern element until...
  801. X     ** - an element match fails, or
  802. X     ** - we run out of src elements (pattern too big)
  803. X     ** - we run out of pattern elements (pattern not sufficient)
  804. X     **/
  805. X
  806. X    iSrcIndex = 0;
  807. X    iPatIndex = 0;
  808. X
  809. X    while (iErr == VEOS_SUCCESS) {    
  810. X
  811. X    /*******************************************************
  812. X     ** first, pass the gauntlet of tests for continuance **
  813. X     *******************************************************/
  814. X
  815. X    /** check for end of pattern **/
  816. X
  817. X    if (iPatIndex >= iPatElts) {
  818. X        if (iSrcIndex != iSrcElts)
  819. X        iErr = NANCY_PatTooShort;
  820. X        break;
  821. X        }
  822. X
  823. X
  824. X    /** setup local info of current pattern element **/
  825. X
  826. X    pPatFinger = &pPatGr->pEltList[iPatIndex];
  827. X    pSrcFinger = &pSrcGr->pEltList[iSrcIndex];
  828. X
  829. X    bMarked = TESTFLAG(NANCY_EltMarkMask, pPatFinger->iFlags);
  830. X    bTouched = TESTFLAG(NANCY_EltTouchMask, pPatFinger->iFlags);
  831. X
  832. X
  833. X    /** check for end of source,
  834. X     ** and not about to insert,
  835. X     ** and matching zero or more.
  836. X     **/
  837. X
  838. X    if (iSrcIndex >= iSrcElts &&
  839. X        pPatFinger->iType != GR_here &&
  840. X        pPatFinger->iType != GR_theseall) {
  841. X
  842. X        /** must be more pattern elts, or would not have got this far **/
  843. X
  844. X        iErr = NANCY_SrcTooShort;
  845. X        break;
  846. X        }
  847. X    
  848. X
  849. X    /**********************************************
  850. X     ** second, perform the element match itself **
  851. X     **********************************************/
  852. X
  853. X    switch (pPatFinger->iType) {
  854. X        
  855. X    case GR_theseall:
  856. X        if (iSrcIndex < iSrcElts) {
  857. X        if (bMarked) {
  858. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  859. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcElts - 1;
  860. X            pMarkPB->iZones ++;
  861. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  862. X            pMarkPB->iInsertElt = iSrcIndex;
  863. X            }
  864. X        else if (bTouched) {
  865. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  866. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcElts - 1;
  867. X            pTouchPB->iZones ++;
  868. X            }
  869. X        iSrcIndex = iSrcElts;
  870. X        }
  871. X        iSrcIndex = iSrcIndex - 1;
  872. X        break;
  873. X
  874. X    case GR_here:
  875. X        pMarkPB->iInsertElt = iSrcIndex;
  876. X        iSrcIndex = iSrcIndex - 1;
  877. X        break;
  878. X    
  879. X    case GR_these:
  880. X        iMoreSrcElts = pPatFinger->u.iVal - 1;
  881. X
  882. X        if (iSrcIndex + iMoreSrcElts >= iSrcElts)
  883. X        iErr = NANCY_SrcTooShort;
  884. X
  885. X        else {
  886. X        if (bMarked) {
  887. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  888. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex + iMoreSrcElts;
  889. X            pMarkPB->iZones ++;
  890. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  891. X            pMarkPB->iInsertElt = iSrcIndex;
  892. X            }
  893. X        else if (bTouched) {
  894. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  895. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight =
  896. X            iSrcIndex + iMoreSrcElts;
  897. X            pTouchPB->iZones ++;
  898. X            }
  899. X        iSrcIndex += iMoreSrcElts;
  900. X        }
  901. X        break;
  902. X
  903. X    case GR_grouple:
  904. X    case GR_vector:
  905. X        if (pPatFinger->iType != pSrcFinger->iType)
  906. X        iErr = NANCY_NoMatch;
  907. X
  908. X        else {
  909. X        pMatchSpec->pSrcGr = pSrcFinger->u.pGr;
  910. X        pMatchSpec->pPatGr = pPatFinger->u.pGr;
  911. X        
  912. X        iErr = Nancy_MatchGrouple(pMatchSpec);
  913. X        
  914. X        pMatchSpec->pSrcGr = pSrcGr;
  915. X        pMatchSpec->pPatGr = pPatGr;
  916. X        
  917. X        if (iErr == VEOS_SUCCESS) {
  918. X            if (bMarked) {
  919. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  920. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  921. X            pMarkPB->iZones ++;
  922. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  923. X                pMarkPB->iInsertElt = iSrcIndex;
  924. X            }
  925. X            else if (bTouched) {
  926. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  927. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  928. X            pTouchPB->iZones ++;
  929. X            }
  930. X            }
  931. X        }
  932. X        break;
  933. X
  934. X    default:
  935. X        iErr = Nancy_EltIdentical(pPatFinger, pSrcFinger);
  936. X        if (iErr == VEOS_SUCCESS) {
  937. X        if (bMarked) {
  938. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  939. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  940. X            pMarkPB->iZones ++;
  941. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  942. X            pMarkPB->iInsertElt = iSrcIndex;
  943. X            }
  944. X        else if (bTouched) {
  945. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  946. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  947. X            pTouchPB->iZones ++;
  948. X            }
  949. X        }
  950. X        break;
  951. X
  952. X        } /* switch */
  953. X
  954. X    iPatIndex ++;
  955. X    iSrcIndex ++;
  956. X    }
  957. X
  958. X    /********************
  959. X     ** third, cleanup **
  960. X     ********************/
  961. X    
  962. X    if (iErr != VEOS_SUCCESS) {
  963. X
  964. X    if (bMarkWithin)
  965. X        Nancy_DisposeReplaceNode(pMarkPB);
  966. X    if (bTouchWithin)
  967. X        Nancy_DisposeReplaceNode(pTouchPB);
  968. X    }
  969. X    else {
  970. X    if (bMarkWithin) {
  971. X        pMarkPB->pNext = pMatchSpec->pReplaceList;
  972. X        pMatchSpec->pReplaceList = pMarkPB;
  973. X        }
  974. X    if (bTouchWithin) {
  975. X        pTouchPB->pNext = pMatchSpec->pTouchList;
  976. X        pMatchSpec->pTouchList = pTouchPB;
  977. X        }
  978. X    }
  979. X    
  980. X    return(iErr);
  981. X
  982. X    } /* MatchPositionGrouple */
  983. X/****************************************************************************************/
  984. X
  985. X
  986. X
  987. X/****************************************************************************************
  988. X * Nancy_MatchContentGrouple                                */
  989. X
  990. XTVeosErr Nancy_MatchContentGrouple(pMatchSpec)
  991. X    TPMatchRec        pMatchSpec;
  992. X{
  993. X    int            iPatElts;
  994. X    int            iPatIndex;
  995. X    TPElt        pWildElt, pPatElt;
  996. X    TPGrouple        pPatGr;
  997. X
  998. X    boolean        bMarkWithin, bTouchWithin;
  999. X    TPReplaceRec    pMarkPB = nil, pTouchPB = nil;
  1000. X    TVeosErr        iErr = VEOS_SUCCESS;
  1001. X
  1002. X
  1003. X    pPatGr = pMatchSpec->pPatGr;
  1004. X    iPatElts = pPatGr->iElts;
  1005. X
  1006. X
  1007. X    /** content addressable grouples are specified
  1008. X     ** very precisely.  ie, there must be at least
  1009. X     ** one element, and the last element must be a * form.
  1010. X     **
  1011. X     ** thus, if a pattern came this far...
  1012. X     ** it better have a * element in last location.
  1013. X     ** so, the last elt type must be GR_any or GR_some.
  1014. X     **/
  1015. X
  1016. X    pWildElt = &pPatGr->pEltList[iPatElts - 1];
  1017. X
  1018. X
  1019. X    /** don't match normally against * form **/
  1020. X    iPatElts --;
  1021. X
  1022. X    
  1023. X    bMarkWithin = TESTFLAG(NANCY_MarkWithinMask, pPatGr->iFlags);
  1024. X    bTouchWithin = TESTFLAG(NANCY_TouchWithinMask, pPatGr->iFlags);
  1025. X
  1026. X    /** setup replace descriptor to pass back.
  1027. X     ** note, many descriptors can be created with one match...
  1028. X     ** for example, when the caller calls this function again
  1029. X     ** during a 'MatchMany' type match.
  1030. X     **/
  1031. X    
  1032. X    if (bMarkWithin) {
  1033. X    Nancy_NewReplaceNode(&pMarkPB);
  1034. X    pMarkPB->pEnviron = pMatchSpec->pSrcGr;
  1035. X    }
  1036. X    if (bTouchWithin) {
  1037. X    Nancy_NewReplaceNode(&pTouchPB);
  1038. X    pTouchPB->pEnviron = pMatchSpec->pSrcGr;
  1039. X    }
  1040. X    
  1041. X    
  1042. X    /** pattern controls the flow 
  1043. X     ** loop through each pattern element until...
  1044. X     ** - an element match fails, or
  1045. X     ** - we run out of pattern elements (match successful)
  1046. X     **/
  1047. X    
  1048. X    for (iPatIndex = 0, pPatElt = pMatchSpec->pPatGr->pEltList;
  1049. X     iErr == VEOS_SUCCESS;
  1050. X     iPatIndex ++, pPatElt ++) {
  1051. X    
  1052. X    
  1053. X    /** check for end of pattern **/
  1054. X    
  1055. X    if (iPatIndex >= iPatElts)
  1056. X        break;
  1057. X    
  1058. X    /** void matches instantly, no match necessary **/
  1059. X
  1060. X    if (pPatElt->iType == GR_here)
  1061. X        pMarkPB->iInsertElt = 0;
  1062. X
  1063. X    /** match pattern element against each elt in src grouple **/
  1064. X
  1065. X    else 
  1066. X        iErr = Nancy_MapMatch(pMatchSpec, iPatIndex, pMarkPB, pTouchPB);
  1067. X
  1068. X    } /* pattern element loop */
  1069. X
  1070. X
  1071. X
  1072. X    Nancy_MapRestore(pMatchSpec,
  1073. X             ((TESTFLAG(NANCY_EltMarkMask, pWildElt->iFlags) &&
  1074. X               iErr == VEOS_SUCCESS) ? TRUE : FALSE),
  1075. X             ((TESTFLAG(NANCY_EltTouchMask, pWildElt->iFlags) &&
  1076. X               iErr == VEOS_SUCCESS) ? TRUE : FALSE),
  1077. X             pMarkPB, pTouchPB);
  1078. X    
  1079. X
  1080. X
  1081. X    /** cleanup **/
  1082. X    
  1083. X    if (iErr != VEOS_SUCCESS) {
  1084. X
  1085. X    if (bMarkWithin)
  1086. X        Nancy_DisposeReplaceNode(pMarkPB);
  1087. X    if (bTouchWithin)
  1088. X        Nancy_DisposeReplaceNode(pTouchPB);
  1089. X    }
  1090. X    else {
  1091. X    if (bMarkWithin) {
  1092. X        pMarkPB->pNext = pMatchSpec->pReplaceList;
  1093. X        pMatchSpec->pReplaceList = pMarkPB;
  1094. X        }
  1095. X    if (bTouchWithin) {
  1096. X        pTouchPB->pNext = pMatchSpec->pTouchList;
  1097. X        pMatchSpec->pTouchList = pTouchPB;
  1098. X        }
  1099. X    }
  1100. X
  1101. X    return(iErr);
  1102. X
  1103. X    } /* MatchContentGrouple */
  1104. X/****************************************************************************************/
  1105. X
  1106. X
  1107. X
  1108. X/****************************************************************************************/
  1109. XTVeosErr Nancy_MapMatch(pMatchSpec, iPatIndex, pMarkPB, pTouchPB)
  1110. X    TPMatchRec        pMatchSpec;
  1111. X    int            iPatIndex;
  1112. X    TPReplaceRec    pMarkPB, pTouchPB;
  1113. X{
  1114. X    int            iSrcElts, iSrcIndex;
  1115. X    TPElt        pSrcFinger, pPatElt;
  1116. X    TPGrouple        pSrcGr, pPatGr;
  1117. X    int            iMatches;
  1118. X    boolean        bPatMarked, bPatTouched;
  1119. X    TVeosErr        iErr = VEOS_SUCCESS;
  1120. X    
  1121. X    
  1122. X    pSrcGr = pMatchSpec->pSrcGr;
  1123. X    iSrcElts = pSrcGr->iElts;
  1124. X    
  1125. X    pPatGr = pMatchSpec->pPatGr;
  1126. X    pPatElt = &pPatGr->pEltList[iPatIndex];
  1127. X    
  1128. X    bPatMarked = TESTFLAG(NANCY_EltMarkMask, pPatElt->iFlags);
  1129. X    bPatTouched = TESTFLAG(NANCY_EltTouchMask, pPatElt->iFlags);
  1130. X    
  1131. X#ifndef OPTIMAL
  1132. X    if (NANCY_BUGS) {
  1133. X    fprintf(stderr, "matching:  ");
  1134. X    Nancy_ElementToStream(pPatElt, stderr);
  1135. X    fprintf(stderr, "against:  ");
  1136. X    Nancy_GroupleToStream(pSrcGr, stderr);
  1137. X    }
  1138. X#endif
  1139. X    
  1140. X    /** perform exhaustive search for pat
  1141. X     ** element through the source grouple.
  1142. X     **/
  1143. X    iMatches = 0;
  1144. X    
  1145. X    switch (pPatElt->iType) {
  1146. X
  1147. X    case GR_grouple:
  1148. X    case GR_vector:
  1149. X    for (iSrcIndex = 0, pSrcFinger = pSrcGr->pEltList;
  1150. X         iSrcIndex < iSrcElts;
  1151. X         iSrcIndex ++, pSrcFinger ++) {
  1152. X        
  1153. X        if (pPatElt->iType == pSrcFinger->iType) {
  1154. X        
  1155. X        pMatchSpec->pSrcGr = pSrcFinger->u.pGr;
  1156. X        pMatchSpec->pPatGr = pPatElt->u.pGr;
  1157. X        
  1158. X        iErr = Nancy_MatchGrouple(pMatchSpec);
  1159. X        
  1160. X        pMatchSpec->pSrcGr = pSrcGr;
  1161. X        pMatchSpec->pPatGr = pPatGr;
  1162. X        
  1163. X        if (iErr == VEOS_SUCCESS) {
  1164. X            
  1165. X            if (bPatMarked) {
  1166. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  1167. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  1168. X            pMarkPB->iZones ++;
  1169. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  1170. X                pMarkPB->iInsertElt = iSrcIndex;
  1171. X            }
  1172. X            else if (bPatTouched) {
  1173. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  1174. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  1175. X            pTouchPB->iZones ++;
  1176. X            }
  1177. X            
  1178. X            iMatches ++;
  1179. X
  1180. X            if (NANCY_BUGS) {
  1181. X            fprintf(stderr, "matched on:    ");
  1182. X            Nancy_ElementToStream(pSrcFinger, stderr);
  1183. X            }            
  1184. X
  1185. X            /** mark src element as having been matched **/
  1186. X            SETFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  1187. X            
  1188. X            if (pMatchSpec->iFreqFlag == NANCY_MatchOne)
  1189. X            break;
  1190. X            
  1191. X            } /* matched */
  1192. X        } /* same type */
  1193. X        } /* for */
  1194. X    break;
  1195. X
  1196. X    default:
  1197. X    for (iSrcIndex = 0, pSrcFinger = pSrcGr->pEltList;
  1198. X         iSrcIndex < iSrcElts;
  1199. X         iSrcIndex ++, pSrcFinger ++) {
  1200. X        
  1201. X        if (pPatElt->iType == pSrcFinger->iType &&
  1202. X        Nancy_EltIdentical(pPatElt, pSrcFinger) == VEOS_SUCCESS) {
  1203. X        
  1204. X        if (bPatMarked) {
  1205. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  1206. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  1207. X            pMarkPB->iZones ++;
  1208. X            if (pMatchSpec->iDestroyFlag == NANCY_ReplaceMatch)
  1209. X            pMarkPB->iInsertElt = iSrcIndex;
  1210. X            }
  1211. X        else if (bPatTouched) {
  1212. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  1213. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  1214. X            pTouchPB->iZones ++;
  1215. X            }
  1216. X        
  1217. X        iMatches ++;
  1218. X
  1219. X        if (NANCY_BUGS) {
  1220. X            fprintf(stderr, "matched on:    ");
  1221. X            Nancy_ElementToStream(pSrcFinger, stderr);
  1222. X            }
  1223. X
  1224. X        /** mark src element as having been matched **/
  1225. X        SETFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  1226. X        
  1227. X        if (pMatchSpec->iFreqFlag == NANCY_MatchOne)
  1228. X            break;
  1229. X        
  1230. X        } /* matched */
  1231. X        } /* for */
  1232. X    break;
  1233. X
  1234. X    } /* switch */
  1235. X    
  1236. X    if (iMatches == 0)
  1237. X    iErr = NANCY_NoMatch;
  1238. X    else
  1239. X    iErr = VEOS_SUCCESS;
  1240. X    
  1241. X    return(iErr);
  1242. X    
  1243. X    } /* Nancy_MapMatch */
  1244. X/****************************************************************************************/
  1245. X
  1246. X
  1247. X
  1248. X/****************************************************************************************/
  1249. XTVeosErr Nancy_MapRestore(pMatchSpec, bGatherUnmatched, bTouchUnmatched, pMarkPB, pTouchPB)
  1250. X    TPMatchRec        pMatchSpec;
  1251. X    boolean        bGatherUnmatched, bTouchUnmatched;
  1252. X    TPReplaceRec    pMarkPB, pTouchPB;
  1253. X{
  1254. X    int            iSrcIndex, iSrcElts;
  1255. X    TPElt        pSrcFinger;
  1256. X    TVeosErr        iErr = VEOS_SUCCESS;
  1257. X    
  1258. X    iSrcElts = pMatchSpec->pSrcGr->iElts;
  1259. X
  1260. X    if (bGatherUnmatched) {
  1261. X
  1262. X    for (iSrcIndex = 0, pSrcFinger = pMatchSpec->pSrcGr->pEltList;
  1263. X         iSrcIndex < iSrcElts; 
  1264. X         iSrcIndex ++, pSrcFinger ++) {
  1265. X
  1266. X        if (TESTFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags)) {
  1267. X        
  1268. X        /** clear the source marks **/
  1269. X        CLRFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  1270. X        }
  1271. X        
  1272. X        else {
  1273. X        /** gather unmatched elements into replace list **/
  1274. X        
  1275. X        if (pMarkPB->pWipeList[pMarkPB->iZones - 1].iRight == (iSrcIndex - 1))
  1276. X            pMarkPB->pWipeList[pMarkPB->iZones - 1].iRight = iSrcIndex;
  1277. X        else {
  1278. X            pMarkPB->pWipeList[pMarkPB->iZones].iLeft = iSrcIndex;
  1279. X            pMarkPB->pWipeList[pMarkPB->iZones].iRight = iSrcIndex;
  1280. X            pMarkPB->iZones ++;
  1281. X            }
  1282. X        }
  1283. X        } /* for */
  1284. X    } /* gather marked */
  1285. X
  1286. X    else if (bTouchUnmatched) {
  1287. X
  1288. X    for (iSrcIndex = 0, pSrcFinger = pMatchSpec->pSrcGr->pEltList;
  1289. X         iSrcIndex < iSrcElts; 
  1290. X         iSrcIndex ++, pSrcFinger ++) {
  1291. X
  1292. X        if (TESTFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags)) {
  1293. X        
  1294. X        /** clear the source marks **/
  1295. X        CLRFLAG(NANCY_EltMatchMask, pSrcFinger->iFlags);
  1296. X        }
  1297. X        
  1298. X        else {
  1299. X        /** gather unmatched elements into touch list **/
  1300. X        
  1301. X        if (pTouchPB->pWipeList[pTouchPB->iZones - 1].iRight == (iSrcIndex - 1))
  1302. X            pTouchPB->pWipeList[pTouchPB->iZones - 1].iRight = iSrcIndex;
  1303. X        else {
  1304. X            pTouchPB->pWipeList[pTouchPB->iZones].iLeft = iSrcIndex;
  1305. X            pTouchPB->pWipeList[pTouchPB->iZones].iRight = iSrcIndex;
  1306. X            pTouchPB->iZones ++;
  1307. X            }
  1308. X        }
  1309. X        } /* for */
  1310. X    } /* gather touch */
  1311. X
  1312. X    return(iErr);
  1313. X
  1314. X    } /* Nancy_MapRestore */
  1315. X/****************************************************************************************
  1316. X
  1317. X
  1318. X
  1319. X/****************************************************************************************
  1320. X * Nancy_NewReplaceNode                                    */
  1321. X
  1322. XTVeosErr Nancy_NewReplaceNode(hNode)
  1323. X    THReplaceRec    hNode;
  1324. X{
  1325. X    TVeosErr         iErr;
  1326. X    TPReplaceRec    pNode;
  1327. X
  1328. X    iErr = Shell_NewBlock(sizeof(TReplaceRec), &pNode, "replace-bp");
  1329. X    if (iErr == VEOS_SUCCESS) {
  1330. X    pNode->pEnviron = nil;
  1331. X    pNode->iZones = 0;
  1332. X    pNode->iInsertElt = -1;
  1333. X    pNode->pNext = nil;
  1334. X    }
  1335. X
  1336. X    *hNode = pNode;
  1337. X
  1338. X    return(iErr);
  1339. X
  1340. X    } /* Nancy_NewReplaceNode */
  1341. X/****************************************************************************************/
  1342. X
  1343. X
  1344. X
  1345. X/****************************************************************************************
  1346. X * Nancy_DisposeReplaceNode                                */
  1347. X
  1348. XTVeosErr Nancy_DisposeReplaceNode(pNode)
  1349. X    TPReplaceRec    pNode;
  1350. X{
  1351. X    TVeosErr         iErr;
  1352. X
  1353. X    iErr = Shell_ReturnBlock(pNode, sizeof(TReplaceRec), "replace-bp");
  1354. X
  1355. X    return(iErr);
  1356. X
  1357. X    } /* Nancy_DisposeReplaceNode */
  1358. X/****************************************************************************************/
  1359. X
  1360. X
  1361. X
  1362. X/****************************************************************************************
  1363. X * Nancy_                                        */
  1364. X
  1365. XTVeosErr Nancy_()
  1366. X{
  1367. X    TVeosErr         iErr;
  1368. X
  1369. X
  1370. X    return(iErr);
  1371. X
  1372. X    } /* Nancy_ */
  1373. X/****************************************************************************************/
  1374. X
  1375. END_OF_FILE
  1376. if test 17745 -ne `wc -c <'src/kernel_current/nancy/nancy_match.c'`; then
  1377.     echo shar: \"'src/kernel_current/nancy/nancy_match.c'\" unpacked with wrong size!
  1378. fi
  1379. # end of 'src/kernel_current/nancy/nancy_match.c'
  1380. fi
  1381. if test -f 'src/kernel_current/talk/socket.c' -a "${1}" != "-c" ; then 
  1382.   echo shar: Will not clobber existing file \"'src/kernel_current/talk/socket.c'\"
  1383. else
  1384. echo shar: Extracting \"'src/kernel_current/talk/socket.c'\" \(16709 characters\)
  1385. sed "s/^X//" >'src/kernel_current/talk/socket.c' <<'END_OF_FILE'
  1386. X/****************************************************************************************
  1387. X *                                            *
  1388. X * file: socket.c                                                *
  1389. X *                                            *
  1390. X * November 14, 1990: The network and transport layer for inter-entity message passing    *
  1391. X *               library, 'talk' for the VEOS project.                             *
  1392. X *                                            *
  1393. X * by Geoffrey P. Coco at the HITLab, Seattle.                          *
  1394. X * these functions are based on BSD socket code by Dan Pezely.                       *
  1395. X *                                            *
  1396. X ****************************************************************************************/
  1397. X
  1398. X/****************************************************************************************
  1399. X * Copyright (C) 1992  Geoffrey P. Coco, Human Interface Technology Lab, Seattle    *
  1400. X ****************************************************************************************/
  1401. X
  1402. X
  1403. X
  1404. X/****************************************************************************************
  1405. X *                      include the papa include file                */
  1406. X
  1407. X#include "kernel.h"
  1408. X
  1409. X#include <sys/types.h>
  1410. X#include <sys/socket.h>
  1411. X#include <netinet/in.h>
  1412. X#include <netinet/tcp.h>
  1413. X#include <netdb.h>            /* for get_*_byname() */
  1414. X#include <stropts.h>            /* ioctl() streamio */
  1415. X#include <fcntl.h>
  1416. X#include "signal.h"
  1417. X
  1418. X/****************************************************************************************/
  1419. X
  1420. X
  1421. X
  1422. X/****************************************************************************************
  1423. X *                     forward function declarations                */
  1424. X
  1425. XTVeosErr Sock_Connect();
  1426. XTVeosErr Sock_Listen();
  1427. XTVeosErr Sock_ReadSelect();
  1428. XTVeosErr Sock_WriteSelect();
  1429. XTVeosErr Sock_Accept();
  1430. XTVeosErr Sock_Transmit();
  1431. XTVeosErr Sock_Receive();
  1432. XTVeosErr Sock_Close();
  1433. X
  1434. X/****************************************************************************************/
  1435. X
  1436. X
  1437. X
  1438. X/****************************************************************************************
  1439. X *                     local function declarations                */
  1440. X
  1441. XTVeosErr Sock_MixItUp();
  1442. XTVeosErr Sock_ResolveHost();
  1443. Xu_long Sock_ConvertAddr();
  1444. X
  1445. X/****************************************************************************************/
  1446. X
  1447. X
  1448. X
  1449. X
  1450. X/****************************************************************************************/
  1451. XTVeosErr Sock_Connect(iSocketFD, pUid, sProtocolName)
  1452. X    int         *iSocketFD;
  1453. X    TPUid        pUid;
  1454. X    char         *sProtocolName;
  1455. X{
  1456. X    struct sockaddr_in  socketName;
  1457. X    TVeosErr        iErr;
  1458. X    int            iProto, iOption, iBufSize;
  1459. X    
  1460. X
  1461. X    /** translate given network params into useable form **/
  1462. X
  1463. X    iErr = Sock_MixItUp(&pUid->iPort, sProtocolName, &iProto);
  1464. X    if (iErr == VEOS_SUCCESS) {
  1465. X
  1466. X
  1467. X    /** copy the address of the receiving host **/
  1468. X
  1469. X    socketName.sin_addr.s_addr = pUid->lHost;
  1470. X
  1471. X        
  1472. X    /** create socket with specified protocol **/
  1473. X    
  1474. X    socketName.sin_family = AF_INET;
  1475. X    socketName.sin_port = htons(pUid->iPort);
  1476. X    
  1477. X    *iSocketFD = socket(socketName.sin_family, SOCK_STREAM, iProto);
  1478. X    
  1479. X    if (*iSocketFD == TALK_BOGUS_FD)
  1480. X        iErr = TALK_CREATE;
  1481. X    
  1482. X    else {
  1483. X        
  1484. X        
  1485. X        /** attempt to connect to given address **/
  1486. X        
  1487. X        if (connect(*iSocketFD, &socketName, sizeof(socketName)) < 0)
  1488. X        
  1489. X        iErr = TALK_CONNECT;
  1490. X        
  1491. X        
  1492. X        else {
  1493. X/*
  1494. X        iBufSize = 16384;
  1495. X        if (setsockopt(*iSocketFD, SOL_SOCKET, SO_SNDBUF,
  1496. X                   (char *) &iBufSize, sizeof(int)) < 0)
  1497. X            iErr = TALK_FLAGS;
  1498. X*/            
  1499. X        iOption = TRUE;
  1500. X        if (setsockopt(*iSocketFD, IPPROTO_TCP, TCP_NODELAY,
  1501. X                   &iOption, sizeof(int)) == -1)
  1502. X            iErr = TALK_FLAGS;
  1503. X
  1504. X        /** set non-blocking write bit **/
  1505. X        
  1506. X        fcntl(*iSocketFD, F_SETFL, FNDELAY);
  1507. X        
  1508. X        FD_SET(*iSocketFD, &OPEN_WRITE_SOCKETS);
  1509. X        }
  1510. X        
  1511. X        if (iErr != VEOS_SUCCESS)
  1512. X        Sock_Close(iSocketFD);
  1513. X        }
  1514. X    }
  1515. X
  1516. X    return(iErr);
  1517. X
  1518. X    } /* Sock_Connect */
  1519. X/****************************************************************************************/
  1520. X
  1521. X
  1522. X
  1523. X
  1524. X/****************************************************************************************/
  1525. XTVeosErr Sock_Listen(iSocketFD, iPortNumber, sProtocolName, iAttitude)
  1526. X    int         *iSocketFD;
  1527. X    int         iPortNumber;
  1528. X    char         *sProtocolName;
  1529. X    int            iAttitude;
  1530. X{
  1531. X    struct sockaddr_in  socketName;
  1532. X    TVeosErr        iErr;
  1533. X    int            iProto, iOption;
  1534. X    int            iZoot;
  1535. X
  1536. X    iErr = Sock_MixItUp(&iPortNumber, sProtocolName, &iProto);
  1537. X    if (iErr == VEOS_SUCCESS) {
  1538. X
  1539. X
  1540. X
  1541. X    /** create socket with specified protocol **/
  1542. X
  1543. X    socketName.sin_family = AF_INET;   /* specify socket to be of INTERNET family */
  1544. X
  1545. X    *iSocketFD = socket(socketName.sin_family, SOCK_STREAM, iProto);
  1546. X
  1547. X    if (*iSocketFD == TALK_BOGUS_FD)
  1548. X        iErr = TALK_CREATE;
  1549. X
  1550. X    else {
  1551. X        socketName.sin_addr.s_addr = htonl(INADDR_ANY);
  1552. X        socketName.sin_port = htons(iPortNumber);
  1553. X        
  1554. X        if (iAttitude == TALK_AGRESSIVE) {
  1555. X        iOption = TRUE;
  1556. X        if (setsockopt(*iSocketFD, SOL_SOCKET, SO_REUSEADDR,
  1557. X                   &iOption, sizeof(int)) == -1)
  1558. X            iErr = TALK_FLAGS;
  1559. X        }
  1560. X        
  1561. X        if (iErr == VEOS_SUCCESS) {
  1562. X        
  1563. X        /** register this socket with system for us **/
  1564. X        
  1565. X        if (bind(*iSocketFD, &socketName, sizeof(socketName)) < 0) {
  1566. X            
  1567. X            iErr = TALK_BIND;
  1568. X            }
  1569. X        
  1570. X        else {
  1571. X            /** listen on the socket **/
  1572. X            
  1573. X            if (listen(*iSocketFD, TALK_QUEUE_SIZE ) < 0)
  1574. X            iErr = TALK_LISTEN;
  1575. X            
  1576. X            else {
  1577. X            /** have this socket generate an interrupt
  1578. X             ** when another entity connects.
  1579. X             **/
  1580. X/*
  1581. X            fcntl(*iSocketFD, F_SETOWN, getpid());
  1582. X            fcntl(*iSocketFD, F_SETFL, FASYNC);
  1583. X*/            
  1584. X            FD_SET(*iSocketFD, &OPEN_READ_SOCKETS);
  1585. X            }
  1586. X            }
  1587. X        }        
  1588. X        }
  1589. X    if (iErr != VEOS_SUCCESS) {
  1590. X        
  1591. X        Sock_Close(iSocketFD);
  1592. X        *iSocketFD = TALK_BOGUS_FD;
  1593. X        }
  1594. X    }
  1595. X
  1596. X    return(iErr);
  1597. X    
  1598. X    } /* Sock_Listen */
  1599. X/****************************************************************************************/
  1600. X
  1601. X
  1602. X
  1603. X
  1604. X/****************************************************************************************/
  1605. XTVeosErr Sock_ReadSelect(iSocketFD)
  1606. X    int        iSocketFD;
  1607. X{
  1608. X    struct timeval      timeVal;
  1609. X    fd_set          tempFDSet;
  1610. X    int         iSize;
  1611. X    TVeosErr        iErr;
  1612. X    
  1613. X    
  1614. X    iErr = VEOS_SUCCESS;
  1615. X    
  1616. X    
  1617. X    /** create a local copy of the fd_set since it gets modified by select() **/
  1618. X    
  1619. X    bcopy((char*) &OPEN_READ_SOCKETS, (char*) &tempFDSet, sizeof(fd_set));
  1620. X    
  1621. X    
  1622. X    
  1623. X    /** some implementations of select() might modify timeVal, so we    **
  1624. X     ** must keep resetting it rather then making it global or static.    **/
  1625. X    
  1626. X    timeVal.tv_sec = 0;
  1627. X    timeVal.tv_usec = 0;
  1628. X    
  1629. X    iSize = select(FD_SETSIZE, &tempFDSet, nil, nil, &timeVal);
  1630. X    
  1631. X    if (iSize <  0)
  1632. X    iErr = TALK_SELECT;
  1633. X    
  1634. X    else if (iSize == 0)
  1635. X    iErr = TALK_SELECT_TIMEOUT;
  1636. X    
  1637. X    else if (!FD_ISSET(iSocketFD, &tempFDSet))
  1638. X    iErr = TALK_NOCONN;
  1639. X    
  1640. X    
  1641. X    return(iErr);
  1642. X    
  1643. X    } /* Sock_ReadSelect */
  1644. X/****************************************************************************************/
  1645. X
  1646. X
  1647. X
  1648. X
  1649. X/****************************************************************************************
  1650. X * Sock_ReadSelect                                    */
  1651. X
  1652. XTVeosErr Sock_WriteSelect(iSocketFD)
  1653. X     int        iSocketFD;
  1654. X{
  1655. X    struct timeval      timeVal;
  1656. X    fd_set          tempFDSet;
  1657. X    int         iSize;
  1658. X    TVeosErr        iErr;
  1659. X    
  1660. X    
  1661. X    iErr = VEOS_SUCCESS;
  1662. X    
  1663. X    
  1664. X    /** create a local copy of the fd_set since it gets modified by select() **/
  1665. X    
  1666. X    bcopy((char*) &OPEN_WRITE_SOCKETS, (char*) &tempFDSet, sizeof(fd_set));
  1667. X    
  1668. X    
  1669. X    
  1670. X    /** some implementations of select() might modify timeVal, so we    **
  1671. X     ** must keep resetting it rather then making it global or static.    **/
  1672. X    
  1673. X    timeVal.tv_sec = 0;
  1674. X    timeVal.tv_usec = 0;
  1675. X    
  1676. X    iSize = select(FD_SETSIZE, nil, &tempFDSet, nil, &timeVal);
  1677. X    
  1678. X    if (TRAP_FLAGS & 0x00000001 << SIGPIPE) {
  1679. X    TRAP_FLAGS = TRAP_FLAGS & ~(0x00000001 << SIGPIPE);
  1680. X    TERMINATE = FALSE;
  1681. X    iErr = TALK_CONN_CLOSED;
  1682. X    }
  1683. X
  1684. X    else if (iSize <  0)
  1685. X    iErr = TALK_SELECT;
  1686. X    
  1687. X    else if (iSize == 0)
  1688. X    iErr = TALK_SELECT_TIMEOUT;
  1689. X    
  1690. X    else if (!FD_ISSET(iSocketFD, &tempFDSet))
  1691. X    iErr = TALK_NOCONN;
  1692. X    
  1693. X    
  1694. X    return(iErr);
  1695. X    
  1696. X    } /* Sock_WriteSelect */
  1697. X/****************************************************************************************/
  1698. X
  1699. X
  1700. X
  1701. X
  1702. X/****************************************************************************************
  1703. X * Sock_Accept                                        */
  1704. X
  1705. XTVeosErr Sock_Accept(iSocketFD, iSocketIOFD)
  1706. X    int         iSocketFD;
  1707. X    int         *iSocketIOFD;
  1708. X{
  1709. X    TVeosErr        iErr;
  1710. X    int            iBufSize;
  1711. X
  1712. X    iErr = TALK_ACCEPT;
  1713. X    
  1714. X    *iSocketIOFD = accept(iSocketFD, nil, nil);
  1715. X    if (*iSocketIOFD >= 0) {
  1716. X
  1717. X        /** setup socket for large buffers and non-blocking reading **/
  1718. X/*
  1719. X    iBufSize = 16384;
  1720. X    if (setsockopt(*iSocketIOFD, SOL_SOCKET, SO_RCVBUF,
  1721. X               (char *) &iBufSize, sizeof(int)) < 0 ||
  1722. X*/
  1723. X    /** convert msgsock to streams message-nondiscard-mode **/
  1724. X
  1725. X    if (fcntl(*iSocketIOFD, F_SETFL, FNDELAY) == -1)
  1726. X        Sock_Close(iSocketIOFD);
  1727. X
  1728. X    else {
  1729. X        FD_SET(*iSocketIOFD, &OPEN_READ_SOCKETS);
  1730. X        iErr = VEOS_SUCCESS;
  1731. X        }
  1732. X    }
  1733. X
  1734. X    return(iErr);
  1735. X    
  1736. X} /* Sock_Accept */
  1737. X/****************************************************************************************/
  1738. X
  1739. X
  1740. X
  1741. X
  1742. X/****************************************************************************************
  1743. X * Sock_Transmit                                        */
  1744. X
  1745. XTVeosErr Sock_Transmit(iSocketFD, sMessage, pLen)
  1746. X    int            iSocketFD;
  1747. X    char        *sMessage;
  1748. X    int            *pLen;
  1749. X{    
  1750. X    int            iNetAction;
  1751. X    TVeosErr        iErr;
  1752. X    boolean        bTrap;
  1753. X
  1754. X    iErr = VEOS_FAILURE;    
  1755. X    
  1756. X
  1757. X    /** send the string to the given socket destination **/
  1758. X    
  1759. X    iNetAction = write(iSocketFD, sMessage, *pLen);
  1760. X
  1761. X    CATCH_TRAP(SIGPIPE, bTrap);
  1762. X    if (bTrap)
  1763. X    iErr = TALK_CONN_CLOSED;
  1764. X
  1765. X
  1766. X    else if (iNetAction < 0) {
  1767. X
  1768. X    /** expected result when can't write **/
  1769. X
  1770. X    if (errno == EAGAIN || errno == EWOULDBLOCK)        
  1771. X        iErr = TALK_SPEAK_BLOCKED;
  1772. X
  1773. X    else
  1774. X        perror("shell: write");
  1775. X        }
  1776. X
  1777. X    else if (iNetAction > 0) {
  1778. X
  1779. X    *pLen = iNetAction;
  1780. X    iErr = VEOS_SUCCESS;
  1781. X    }
  1782. X
  1783. X    return(iErr);
  1784. X
  1785. X    } /* Sock_Transmit */
  1786. X/****************************************************************************************/
  1787. X
  1788. X
  1789. X
  1790. X
  1791. X/****************************************************************************************
  1792. X * Sock_Receive                                            */
  1793. X
  1794. XTVeosErr Sock_Receive(iSocketFD, sBuffer, iBufferSize)
  1795. X    int            iSocketFD;
  1796. X    char        *sBuffer;
  1797. X    int            *iBufferSize;
  1798. X{
  1799. X    TVeosErr            iErr;
  1800. X    int            iNetAction;
  1801. X
  1802. X
  1803. X    iErr = VEOS_FAILURE;                /* pessimism */
  1804. X
  1805. X
  1806. X    /** look for unread data in socket **/
  1807. X
  1808. X    iNetAction = read(iSocketFD, sBuffer, *iBufferSize);
  1809. X
  1810. X
  1811. X
  1812. X    /** connection still open, but no data **/
  1813. X
  1814. X    if (iNetAction < 0) {
  1815. X
  1816. X    /** expected result when no data **/
  1817. X
  1818. X    if (errno == EAGAIN || errno == EWOULDBLOCK)        
  1819. X        iErr = TALK_LISTEN_BLOCKED;
  1820. X
  1821. X    else
  1822. X        perror("shell: read");
  1823. X        }
  1824. X
  1825. X
  1826. X    /** there was some data in the socket **/
  1827. X
  1828. X    else if (iNetAction > 0) {
  1829. X
  1830. X    iErr = VEOS_SUCCESS;
  1831. X    *iBufferSize = iNetAction;
  1832. X    }
  1833. X
  1834. X
  1835. X    /** conneciton closed from other end **/
  1836. X
  1837. X    else
  1838. X        iErr = TALK_CONN_CLOSED;
  1839. X
  1840. X
  1841. X    return(iErr);
  1842. X
  1843. X    } /* Sock_Receive */
  1844. X/****************************************************************************************/
  1845. X
  1846. X
  1847. X
  1848. X
  1849. X/****************************************************************************************
  1850. X ** Inet Socket Close
  1851. X **
  1852. X ** usage:  status = Sock_Close( &socketFD );
  1853. X ** params: pointer to file descriptor of socket
  1854. X ** returns: VEOS_SUCCESS or TALK_CLOSE
  1855. X **/
  1856. X
  1857. XTVeosErr Sock_Close(iSocketFD)
  1858. X    int           *iSocketFD;
  1859. X{
  1860. X    TVeosErr    iErr;
  1861. X    
  1862. X    iErr = VEOS_SUCCESS;    
  1863. X
  1864. X
  1865. X    if (*iSocketFD != TALK_BOGUS_FD) {
  1866. X    
  1867. X    FD_CLR(*iSocketFD, &OPEN_WRITE_SOCKETS);
  1868. X    FD_CLR(*iSocketFD, &OPEN_READ_SOCKETS);
  1869. X
  1870. X    shutdown(*iSocketFD, 2);
  1871. X
  1872. X    if (close(*iSocketFD) == -1)
  1873. X        iErr = TALK_CLOSE;
  1874. X
  1875. X    else
  1876. X        *iSocketFD = TALK_BOGUS_FD;
  1877. X    }
  1878. X
  1879. X    return(iErr);
  1880. X
  1881. X} /* Sock_Close */
  1882. X/****************************************************************************************/
  1883. X
  1884. X
  1885. X
  1886. X
  1887. X/****************************************************************************************
  1888. X *                           local routines                    *
  1889. X ****************************************************************************************/
  1890. X
  1891. X
  1892. X
  1893. X/****************************************************************************************
  1894. X * Sock_MixItUp                                        */
  1895. X
  1896. XTVeosErr Sock_MixItUp(iPortNumber, sProtocolName, iProto)
  1897. X    char        *sProtocolName;
  1898. X    int            *iPortNumber, *iProto;
  1899. X{
  1900. X    struct protoent     *protocolInfo, *getprotobyname();
  1901. X    TVeosErr        iErr;
  1902. X
  1903. X    iErr = VEOS_FAILURE;
  1904. X
  1905. X    if (*iPortNumber > 0) {
  1906. X
  1907. X    protocolInfo = getprotobyname(sProtocolName);
  1908. X    if (protocolInfo == nil)
  1909. X        iErr = TALK_PROTOCOL;
  1910. X
  1911. X    else {
  1912. X        *iProto = protocolInfo->p_proto;
  1913. X        iErr = VEOS_SUCCESS;
  1914. X        }
  1915. X    }
  1916. X
  1917. X    return(iErr);
  1918. X
  1919. X    } /* Sock_MixItUp */
  1920. X/****************************************************************************************/
  1921. X
  1922. X
  1923. X
  1924. X
  1925. X/****************************************************************************************/
  1926. XTVeosErr Sock_ResolveHost(sHostName, pIpAddr)
  1927. X    char        *sHostName;
  1928. X    u_long        *pIpAddr;
  1929. X{
  1930. X    TVeosErr        iErr;
  1931. X
  1932. X
  1933. X    /** host address may already be in internet form **/
  1934. X
  1935. X    if (isdigit(sHostName[0]))
  1936. X    iErr = Sock_StrAddr2IP(sHostName, pIpAddr);
  1937. X
  1938. X    else
  1939. X    iErr = Sock_StrHost2IP(sHostName, pIpAddr);
  1940. X
  1941. X
  1942. X    return(iErr);
  1943. X
  1944. X} /* Sock_ResolveHost */
  1945. X/****************************************************************************************/
  1946. X
  1947. X
  1948. X
  1949. X/****************************************************************************************/
  1950. XTVeosErr Sock_StrHost2IP(sHostName, pIpAddr)
  1951. X    char     *sHostName;
  1952. X    u_long    *pIpAddr;
  1953. X{
  1954. X    TVeosErr        iErr;
  1955. X    struct hostent      *hostInfo, *gethostbyname();
  1956. X    TPHostNode        pFinger;
  1957. X
  1958. X    iErr = VEOS_FAILURE;
  1959. X
  1960. X    if (sHostName) {
  1961. X
  1962. X    /** try to find this host in hash table first **/
  1963. X
  1964. X    for (pFinger = SOCK_HOSTS[sHostName[0] - 'a'];
  1965. X         pFinger;
  1966. X         pFinger = pFinger->pNext) {
  1967. X
  1968. X        if (strcmp(pFinger->sHostName, sHostName) == 0) {
  1969. X        iErr = VEOS_SUCCESS;
  1970. X        break;
  1971. X        }
  1972. X        }
  1973. X
  1974. X
  1975. X    if (!pFinger) {
  1976. X
  1977. X        /** find host by calling unix kernel **/
  1978. X
  1979. X        iErr = TALK_HOST;            
  1980. X        if (hostInfo = gethostbyname(sHostName)) {
  1981. X
  1982. X        iErr = Shell_NewBlock(sizeof(THostNode), &pFinger, "host-node");
  1983. X        if (iErr == VEOS_SUCCESS) {
  1984. X            
  1985. X            pFinger->sHostName = strdup(sHostName);
  1986. X            pFinger->lHost = *(u_long *) hostInfo->h_addr_list[0];
  1987. X            
  1988. X            
  1989. X            /** insert new host into hash table **/
  1990. X            
  1991. X            pFinger->pNext = SOCK_HOSTS[sHostName[0] - 'a'];
  1992. X            SOCK_HOSTS[sHostName[0] - 'a'] = pFinger;
  1993. X            }
  1994. X        }
  1995. X        }
  1996. X
  1997. X    if (pFinger)
  1998. X        *pIpAddr = pFinger->lHost;
  1999. X    }
  2000. X
  2001. X    return(iErr);
  2002. X
  2003. X    } /* Sock_StrHost2IP */
  2004. X/****************************************************************************************/
  2005. X
  2006. X
  2007. X
  2008. X
  2009. X/****************************************************************************************/
  2010. XTVeosErr Sock_IP2StrHost(lIPAddr, sHostName)
  2011. X    u_long    lIPAddr;
  2012. X    char     *sHostName;
  2013. X{
  2014. X    TVeosErr        iErr;
  2015. X    struct hostent      *hostInfo, *gethostbyaddr();
  2016. X    char        *pFinger;
  2017. X
  2018. X    iErr = VEOS_FAILURE;
  2019. X
  2020. X    if (sHostName) {
  2021. X
  2022. X    if (hostInfo = gethostbyaddr((char *) &lIPAddr, sizeof(u_long), AF_INET)) {
  2023. X        strcpy(sHostName, hostInfo->h_name);
  2024. X
  2025. X        if (pFinger = strchr(sHostName, '.'))
  2026. X        pFinger[0] = '\0';
  2027. X
  2028. X        iErr = VEOS_SUCCESS;
  2029. X        }
  2030. X    else
  2031. X        iErr = TALK_HOST;            
  2032. X    }
  2033. X
  2034. X    return(iErr);
  2035. X
  2036. X    } /* Sock_IP2StrHost */
  2037. X/****************************************************************************************/
  2038. X
  2039. X
  2040. X
  2041. X
  2042. X/****************************************************************************************/
  2043. XTVeosErr Sock_StrAddr2IP(sHostName, pIpAddr)
  2044. X    char     *sHostName;
  2045. X    u_long    *pIpAddr;
  2046. X{
  2047. X    u_long    lResult, lTemp;
  2048. X    char     *pCharFinger;
  2049. X    TVeosErr    iErr;
  2050. X
  2051. X    iErr = VEOS_FAILURE;
  2052. X    if (sHostName) {
  2053. X    
  2054. X    lResult = 0;
  2055. X    pCharFinger = sHostName;  
  2056. X    
  2057. X    
  2058. X    /* first byte */
  2059. X    lTemp = (u_long) atoi(pCharFinger);
  2060. X    lResult |= lTemp << 24;
  2061. X    
  2062. X    
  2063. X    /* second byte */
  2064. X    pCharFinger = strchr(pCharFinger, '.');
  2065. X    pCharFinger ++;
  2066. X    
  2067. X    lTemp = (u_long) atoi(pCharFinger);
  2068. X    lResult |= lTemp << 16;
  2069. X    
  2070. X    
  2071. X    /* third byte */
  2072. X    pCharFinger = strchr(pCharFinger, '.');
  2073. X    pCharFinger ++;
  2074. X    
  2075. X    lTemp = (u_long) atoi(pCharFinger);
  2076. X    lResult |= lTemp << 8;
  2077. X    
  2078. X    
  2079. X    /* fourth byte */
  2080. X    pCharFinger = strchr(pCharFinger, '.');
  2081. X    pCharFinger ++;
  2082. X    
  2083. X    lTemp = (u_long) atoi(pCharFinger);
  2084. X    lResult |= lTemp;
  2085. X    
  2086. X    
  2087. X    *pIpAddr = lResult;
  2088. X
  2089. X    iErr = VEOS_SUCCESS;
  2090. X    }
  2091. X
  2092. X    return(iErr);
  2093. X
  2094. X    } /* Sock_StrAddr2IP */
  2095. X/****************************************************************************************/
  2096. X
  2097. X
  2098. X
  2099. X/****************************************************************************************/
  2100. XTVeosErr Sock_IP2StrAddr(lIpAddr, sHostName)
  2101. X    u_long    lIpAddr;
  2102. X    char     *sHostName;
  2103. X{
  2104. X    TVeosErr        iErr;
  2105. X
  2106. X    iErr = VEOS_FAILURE;
  2107. X    if (sHostName) {
  2108. X    
  2109. X    sprintf(sHostName, "%d.%d.%d.%d",
  2110. X        (lIpAddr >> 24) & 0x000000FF,
  2111. X        (lIpAddr >> 16) & 0x000000FF,
  2112. X        (lIpAddr >> 8) & 0x000000FF,
  2113. X        lIpAddr & 0x000000FF);
  2114. X
  2115. X    iErr = VEOS_SUCCESS;
  2116. X    }
  2117. X
  2118. X    return(iErr);
  2119. X
  2120. X    } /* Sock_IP2StrAddr */
  2121. X/****************************************************************************************/
  2122. X
  2123. X
  2124. X
  2125. X
  2126. X
  2127. X
  2128. END_OF_FILE
  2129. if test 16709 -ne `wc -c <'src/kernel_current/talk/socket.c'`; then
  2130.     echo shar: \"'src/kernel_current/talk/socket.c'\" unpacked with wrong size!
  2131. fi
  2132. # end of 'src/kernel_current/talk/socket.c'
  2133. fi
  2134. if test -f 'src/xlisp/xcore/c/xldmem.c' -a "${1}" != "-c" ; then 
  2135.   echo shar: Will not clobber existing file \"'src/xlisp/xcore/c/xldmem.c'\"
  2136. else
  2137. echo shar: Extracting \"'src/xlisp/xcore/c/xldmem.c'\" \(18074 characters\)
  2138. sed "s/^X//" >'src/xlisp/xcore/c/xldmem.c' <<'END_OF_FILE'
  2139. X/* -*-C-*-
  2140. X********************************************************************************
  2141. X*
  2142. X* File:         xldmem.c
  2143. X* RCS:          $Header: xldmem.c,v 1.6 89/11/25 05:18:06 mayer Exp $
  2144. X* Description:  xlisp dynamic memory management routines.
  2145. X* Author:       David Michael Betz; Niels Mayer
  2146. X* Created:      
  2147. X* Modified:     Sat Nov 25 05:17:34 1989 (Niels Mayer) mayer@hplnpm
  2148. X* Language:     C
  2149. X* Package:      N/A
  2150. X* Status:       X11r4 contrib tape release
  2151. X*
  2152. X* WINTERP 1.0 Copyright 1989 Hewlett-Packard Company (by Niels Mayer).
  2153. X* XLISP version 2.1, Copyright (c) 1989, by David Betz.
  2154. X*
  2155. X* Permission to use, copy, modify, distribute, and sell this software and its
  2156. X* documentation for any purpose is hereby granted without fee, provided that
  2157. X* the above copyright notice appear in all copies and that both that
  2158. X* copyright notice and this permission notice appear in supporting
  2159. X* documentation, and that the name of Hewlett-Packard and David Betz not be
  2160. X* used in advertising or publicity pertaining to distribution of the software
  2161. X* without specific, written prior permission.  Hewlett-Packard and David Betz
  2162. X* make no representations about the suitability of this software for any
  2163. X* purpose. It is provided "as is" without express or implied warranty.
  2164. X*
  2165. X* HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  2166. X* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  2167. X* IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  2168. X* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  2169. X* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  2170. X* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  2171. X* PERFORMANCE OF THIS SOFTWARE.
  2172. X*
  2173. X* See ./winterp/COPYRIGHT for information on contacting the authors.
  2174. X* 
  2175. X* Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  2176. X* Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  2177. X*
  2178. X********************************************************************************
  2179. X*/
  2180. Xstatic char rcs_identity[] = "@(#)$Header: xldmem.c,v 1.6 89/11/25 05:18:06 mayer Exp $";
  2181. X
  2182. X
  2183. X#include "xlisp.h"
  2184. X
  2185. X/* node flags */
  2186. X#define MARK    1
  2187. X#define LEFT    2
  2188. X
  2189. X/* macro to compute the size of a segment */
  2190. X#define segsize(n) (sizeof(SEGMENT)+((n)-1)*sizeof(struct node))
  2191. X
  2192. X/* external variables */
  2193. Xextern LVAL obarray,s_gcflag,s_gchook,s_unbound,true;
  2194. Xextern LVAL xlenv,xlfenv,xldenv;
  2195. Xextern char buf[];
  2196. X
  2197. X/* variables local to xldmem.c and xlimage.c */
  2198. XSEGMENT *segs,*lastseg,*fixseg,*charseg;
  2199. Xint anodes,nsegs,gccalls;
  2200. Xlong nnodes,nfree,total;
  2201. XLVAL fnodes;
  2202. X
  2203. X/* external procedures */
  2204. Xextern char *malloc();
  2205. Xextern char *calloc();
  2206. X
  2207. X/* forward declarations */
  2208. XFORWARD LVAL newnode();
  2209. XFORWARD unsigned char *stralloc();
  2210. XFORWARD SEGMENT *newsegment();
  2211. X
  2212. X/* Include hybrid-class functions: *//* JSP */
  2213. X#define MODULE_XLDMEM_C_GLOBALS
  2214. X#include "../../xmodules.h"
  2215. X#undef MODULE_XLDMEM_C_GLOBALS
  2216. X
  2217. X/* cons - construct a new cons node */
  2218. XLVAL cons(x,y)
  2219. X  LVAL x,y;
  2220. X{
  2221. X    LVAL nnode;
  2222. X
  2223. X    /* get a free node */
  2224. X    if ((nnode = fnodes) == NIL) {
  2225. X    xlstkcheck(2);
  2226. X    xlprotect(x);
  2227. X    xlprotect(y);
  2228. X    gc();
  2229. X    if ((nnode = fnodes) == NIL)
  2230. X        xlabort("insufficient node space");
  2231. X    xlpop();
  2232. X    xlpop();
  2233. X    }
  2234. X
  2235. X    /* unlink the node from the free list */
  2236. X    fnodes = cdr(nnode);
  2237. X    --nfree;
  2238. X
  2239. X    /* initialize the new node */
  2240. X    nnode->n_type = CONS;
  2241. X    rplaca(nnode,x);
  2242. X    rplacd(nnode,y);
  2243. X
  2244. X    /* return the new node */
  2245. X    return (nnode);
  2246. X}
  2247. X
  2248. X/* cvstring - convert a string to a string node */
  2249. XLVAL cvstring(str)
  2250. X  char *str;
  2251. X{
  2252. X    LVAL val;
  2253. X    xlsave1(val);
  2254. X    val = newnode(STRING);
  2255. X    val->n_strlen = strlen(str) + 1;
  2256. X    val->n_string = stralloc(getslength(val));
  2257. X    strcpy(getstring(val),str);
  2258. X    xlpop();
  2259. X    return (val);
  2260. X}
  2261. X
  2262. X/* newstring - allocate and initialize a new string */
  2263. XLVAL newstring(size)
  2264. X  int size;
  2265. X{
  2266. X    LVAL val;
  2267. X    xlsave1(val);
  2268. X    val = newnode(STRING);
  2269. X    val->n_strlen = size;
  2270. X    val->n_string = stralloc(getslength(val));
  2271. X    strcpy(getstring(val),"");
  2272. X    xlpop();
  2273. X    return (val);
  2274. X}
  2275. X
  2276. X/* cvsymbol - convert a string to a symbol */
  2277. XLVAL cvsymbol(pname)
  2278. X  char *pname;
  2279. X{
  2280. X    LVAL val;
  2281. X    xlsave1(val);
  2282. X    val = newvector(SYMSIZE);
  2283. X    val->n_type = SYMBOL;
  2284. X    setvalue(val,s_unbound);
  2285. X    setfunction(val,s_unbound);
  2286. X    setpname(val,cvstring(pname));
  2287. X    xlpop();
  2288. X    return (val);
  2289. X}
  2290. X
  2291. X/* cvsubr - convert a function to a subr or fsubr */
  2292. XLVAL cvsubr(fcn,type,offset)
  2293. X  LVAL (*fcn)(); int type,offset;
  2294. X{
  2295. X    LVAL val;
  2296. X    val = newnode(type);
  2297. X    val->n_subr = fcn;
  2298. X    val->n_offset = offset;
  2299. X    return (val);
  2300. X}
  2301. X
  2302. X/* cvfile - convert a file pointer to a stream */
  2303. XLVAL cvfile(fp)
  2304. X  FILE *fp;
  2305. X{
  2306. X    LVAL val;
  2307. X    val = newnode(STREAM);
  2308. X    setfile(val,fp);
  2309. X    setsavech(val,'\0');
  2310. X    return (val);
  2311. X}
  2312. X
  2313. X/* cvfixnum - convert an integer to a fixnum node */
  2314. XLVAL cvfixnum(n)
  2315. X  FIXTYPE n;
  2316. X{
  2317. X    LVAL val;
  2318. X    if (n >= SFIXMIN && n <= SFIXMAX)
  2319. X    return (&fixseg->sg_nodes[(int)n-SFIXMIN]);
  2320. X    val = newnode(FIXNUM);
  2321. X    val->n_fixnum = n;
  2322. X    return (val);
  2323. X}
  2324. X
  2325. X/* cvflonum - convert a floating point number to a flonum node */
  2326. XLVAL cvflonum(n)
  2327. X  FLOTYPE n;
  2328. X{
  2329. X    LVAL val;
  2330. X    val = newnode(FLONUM);
  2331. X    val->n_flonum = n;
  2332. X    return (val);
  2333. X}
  2334. X
  2335. X/* cvchar - convert an integer to a character node */
  2336. XLVAL cvchar(n)
  2337. X  int n;
  2338. X{
  2339. X    if (n >= CHARMIN && n <= CHARMAX)
  2340. X    return (&charseg->sg_nodes[n-CHARMIN]);
  2341. X    xlerror("character code out of range",cvfixnum((FIXTYPE)n));
  2342. X}
  2343. X
  2344. X/* newustream - create a new unnamed stream */
  2345. XLVAL newustream()
  2346. X{
  2347. X    LVAL val;
  2348. X    val = newnode(USTREAM);
  2349. X    sethead(val,NIL);
  2350. X    settail(val,NIL);
  2351. X    return (val);
  2352. X}
  2353. X
  2354. X/* newobject - allocate and initialize a new object */
  2355. XLVAL newobject(cls,size)
  2356. X  LVAL cls; int size;
  2357. X{
  2358. X    LVAL val;
  2359. X    val = newvector(size+1);
  2360. X    val->n_type = OBJECT;
  2361. X    setelement(val,0,cls);
  2362. X    return (val);
  2363. X}
  2364. X
  2365. X/* newclosure - allocate and initialize a new closure */
  2366. XLVAL newclosure(name,type,env,fenv)
  2367. X  LVAL name,type,env,fenv;
  2368. X{
  2369. X    LVAL val;
  2370. X    val = newvector(CLOSIZE);
  2371. X    val->n_type = CLOSURE;
  2372. X    setname(val,name);
  2373. X    settype(val,type);
  2374. X    setenv(val,env);
  2375. X    setfenv(val,fenv);
  2376. X    return (val);
  2377. X}
  2378. X
  2379. X/* newstruct - allocate and initialize a new structure node */
  2380. XLVAL newstruct(type,size)
  2381. X  LVAL type; int size;
  2382. X{
  2383. X    LVAL val;
  2384. X    val = newvector(size+1);
  2385. X    val->n_type = STRUCT;
  2386. X    setelement(val,0,type);
  2387. X    return (val);
  2388. X}
  2389. X
  2390. X/* newvector - allocate and initialize a new vector node */
  2391. XLVAL newvector(size)
  2392. X  int size;
  2393. X{
  2394. X    LVAL vect;
  2395. X    int bsize;
  2396. X    xlsave1(vect);
  2397. X    vect = newnode(VECTOR);
  2398. X    vect->n_vsize = 0;
  2399. X    if (bsize = size * sizeof(LVAL)) {
  2400. X    if ((vect->n_vdata = (LVAL *)calloc(1,bsize)) == NULL) {
  2401. X        gc();
  2402. Xprintf( "\nnewvector .A:  size d= %d, bsize d= %d", size, bsize );
  2403. X        if ((vect->n_vdata = (LVAL *)calloc(1,bsize)) == NULL)
  2404. X        xlfail("insufficient vector space");
  2405. X    }
  2406. X    vect->n_vsize = size;
  2407. X    total += (long) bsize;
  2408. X    }
  2409. X    xlpop();
  2410. X    return (vect);
  2411. X}
  2412. X
  2413. X/* newnode - allocate a new node */
  2414. XLOCAL LVAL newnode(type)
  2415. X  int type;
  2416. X{
  2417. X    LVAL nnode;
  2418. X
  2419. X    /* get a free node */
  2420. X    if ((nnode = fnodes) == NIL) {
  2421. X    gc();
  2422. X    if ((nnode = fnodes) == NIL)
  2423. X        xlabort("insufficient node space");
  2424. X    }
  2425. X
  2426. X    /* unlink the node from the free list */
  2427. X    fnodes = cdr(nnode);
  2428. X    nfree -= 1L;
  2429. X
  2430. X    /* initialize the new node */
  2431. X    nnode->n_type = type;
  2432. X    rplacd(nnode,NIL);
  2433. X
  2434. X    /* return the new node */
  2435. X    return (nnode);
  2436. X}
  2437. X
  2438. X/* stralloc - allocate memory for a string adding a byte for the terminator */
  2439. XLOCAL unsigned char *stralloc(size)
  2440. X  int size;
  2441. X{
  2442. X    unsigned char *sptr;
  2443. X
  2444. X    /* allocate memory for the string copy */
  2445. X    if ((sptr = (unsigned char *)malloc(size)) == NULL) {
  2446. X    gc();  
  2447. X    if ((sptr = (unsigned char *)malloc(size)) == NULL)
  2448. X        xlfail("insufficient string space");
  2449. X    }
  2450. X    total += (long)size;
  2451. X
  2452. X    /* return the new string memory */
  2453. X    return (sptr);
  2454. X}
  2455. X
  2456. X/* gc - garbage collect (only called here and in xlimage.c) */
  2457. Xgc()
  2458. X{
  2459. X    register LVAL **p,*ap,tmp;
  2460. X    char buf[STRMAX+1];
  2461. X    LVAL *newfp,fun;
  2462. X
  2463. X    /* print the start of the gc message */
  2464. X    if (s_gcflag && getvalue(s_gcflag)) {
  2465. X    sprintf(buf,"[ gc: total %ld, ",nnodes);
  2466. X    stdputstr(buf);
  2467. X    }
  2468. X
  2469. X/* Include hybrid-class functions: *//* JSP */
  2470. X#define MODULE_XLDMEM_C_GC
  2471. X#include "../../xmodules.h"
  2472. X#undef MODULE_XLDMEM_C_GC
  2473. X
  2474. X    /* mark the obarray, the argument list and the current environment */
  2475. X    if (obarray)   mark(obarray);
  2476. X    if (xlenv)     mark(xlenv  );
  2477. X    if (xlfenv)    mark(xlfenv );
  2478. X    if (xldenv)    mark(xldenv );
  2479. X
  2480. X
  2481. X    /* mark the evaluation stack */
  2482. X    for (p = xlstack; p < xlstktop; ++p) {
  2483. X    if (tmp = **p)   mark(tmp);
  2484. X    }
  2485. X
  2486. X    /* mark the argument stack */
  2487. X    for (ap = xlargstkbase; ap < xlsp; ++ap) {
  2488. X    if (tmp = *ap)   mark(tmp);
  2489. X    }
  2490. X
  2491. X    /* sweep memory collecting all unmarked nodes */
  2492. X    sweep();
  2493. X
  2494. X    /* count the gc call */
  2495. X    ++gccalls;
  2496. X
  2497. X    if (nfree < (long)anodes)   addseg();     /*91Jan17jsp*/
  2498. X
  2499. X    /* Call the *gc-hook* if necessary */
  2500. X    if (s_gchook                   != NIL   &&
  2501. X        (fun = getvalue(s_gchook)) != NIL
  2502. X    ) {
  2503. X
  2504. X    /* Rebind the hook fn to NIL: *//*91Jan17jsp*/
  2505. X    LVAL olddenv = xldenv;            /*91Jan17jsp*/
  2506. X    xldbind(s_gchook,NIL);            /*91Jan17jsp*/
  2507. X
  2508. X    newfp = xlsp;
  2509. X    pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
  2510. X    pusharg(fun);
  2511. X    pusharg(cvfixnum((FIXTYPE)2));
  2512. X    pusharg(cvfixnum((FIXTYPE)nnodes));
  2513. X    pusharg(cvfixnum((FIXTYPE)nfree));
  2514. X    xlfp = newfp;
  2515. X
  2516. X    xlapply(2);
  2517. X
  2518. X    /* Restore *GC-HOOK* binding: *//*91Jan17jsp*/
  2519. X    xlunbind(olddenv);        /*91Jan17jsp*/
  2520. X    }
  2521. X
  2522. X    /* print the end of the gc message */
  2523. X    if (s_gcflag && getvalue(s_gcflag)) {
  2524. X    sprintf(buf,"%ld free ]\n",nfree);
  2525. X    stdputstr(buf);
  2526. X    }
  2527. X}
  2528. X
  2529. X/* mark - mark all accessible nodes */
  2530. XLOCAL mark(ptr)
  2531. X  LVAL ptr;
  2532. X{
  2533. X    register LVAL this,prev,tmp;
  2534. X    int type,i,n;
  2535. X
  2536. X    /* initialize */
  2537. X    prev = NIL;
  2538. X    this = ptr;
  2539. X
  2540. X    /* mark this list */
  2541. X    for (;;) {
  2542. X
  2543. X    /* descend as far as we can */
  2544. X    while (!(this->n_flags & MARK)) {
  2545. X
  2546. X        /* check cons and unnamed stream nodes */
  2547. X        if ((type = ntype(this)) == CONS || type == USTREAM) {
  2548. X
  2549. X        if (tmp = car(this)) {
  2550. X
  2551. X            this->n_flags |= MARK|LEFT;
  2552. X            rplaca(this,prev);
  2553. X
  2554. X        } else if (tmp = cdr(this)) {
  2555. X
  2556. X            this->n_flags |= MARK;
  2557. X            rplacd(this,prev);
  2558. X
  2559. X        } else {                /* both sides nil */
  2560. X
  2561. X            this->n_flags |= MARK;
  2562. X            break;
  2563. X        }
  2564. X        prev = this;            /* step down the branch */
  2565. X        this = tmp;
  2566. X
  2567. X        } else {
  2568. X
  2569. X        /* mark other node types */
  2570. X        this->n_flags |= MARK;
  2571. X        switch (type) {
  2572. X/* Include hybrid-class functions: *//* JSP */
  2573. X#define MODULE_XLDMEM_C_MARK
  2574. X#include "../../xmodules.h"
  2575. X#undef MODULE_XLDMEM_C_MARK
  2576. X        case SYMBOL:
  2577. X        case OBJECT:
  2578. X        case VECTOR:
  2579. X        case CLOSURE:
  2580. X        case STRUCT:
  2581. X                vector:
  2582. X            for (i = 0, n = getsz(this); --n >= 0; ++i)
  2583. X            if (tmp = getelement(this,i))
  2584. X                mark(tmp);
  2585. X            break;
  2586. X        }
  2587. X        break;
  2588. X        }
  2589. X        }
  2590. X
  2591. X    /* backup to a point where we can continue descending */
  2592. X    for (;;) {
  2593. X
  2594. X        /* make sure there is a previous node */
  2595. X        if (!prev) {
  2596. X                /* no previous node, must be done */
  2597. X        return;
  2598. X
  2599. X        } else {
  2600. X
  2601. X        if (prev->n_flags &   LEFT) {    /* came from left side */
  2602. X            prev->n_flags &= ~LEFT;
  2603. X            tmp = car(prev);
  2604. X            rplaca(prev,this);
  2605. X            if (this = cdr(prev)) {
  2606. X            rplacd(prev,tmp);            
  2607. X            break;
  2608. X            }
  2609. X        } else {                        /* came from right side */
  2610. X            tmp = cdr(prev);
  2611. X            rplacd(prev,this);
  2612. X        }
  2613. X        this = prev;            /* step back up the branch */
  2614. X        prev = tmp;
  2615. X        }
  2616. X        }
  2617. X    }
  2618. X}
  2619. X
  2620. X/* sweep - sweep all unmarked nodes and add them to the free list */
  2621. XLOCAL sweep()
  2622. X{
  2623. X    SEGMENT *seg;
  2624. X    LVAL p;
  2625. X    int n;
  2626. X
  2627. X    /* empty the free list */
  2628. X    fnodes = NIL;
  2629. X    nfree = 0L;
  2630. X
  2631. X    /* add all unmarked nodes */
  2632. X    for (seg = segs; seg; seg = seg->sg_next) {
  2633. X    if (seg == fixseg)     /* don't sweep the fixnum segment */
  2634. X        continue;
  2635. X    else if (seg == charseg) /* don't sweep the character segment */
  2636. X        continue;
  2637. X    p = &seg->sg_nodes[0];
  2638. X    for (n = seg->sg_size; --n >= 0; ++p) {
  2639. X        if (p->n_flags &   MARK) {
  2640. X        p->n_flags &= ~MARK;
  2641. X        } else {
  2642. X        switch (ntype(p)) {
  2643. X        case STRING:
  2644. X            if (getstring(p) != NULL) {
  2645. X                total -= (long)getslength(p);
  2646. X                free(getstring(p));
  2647. X            }
  2648. X            break;
  2649. X        case STREAM:
  2650. X            if (getfile(p))
  2651. X                osclose(getfile(p));
  2652. X            break;
  2653. X/* Include hybrid-class functions: *//* JSP */
  2654. X#define MODULE_XLDMEM_C_SWEEP
  2655. X#include "../../xmodules.h"
  2656. X#undef MODULE_XLDMEM_C_SWEEP
  2657. X        case SYMBOL:
  2658. X        case OBJECT:
  2659. X        case VECTOR:
  2660. X        case CLOSURE:
  2661. X        case STRUCT:
  2662. X            vector:
  2663. X            if (p->n_vsize) {
  2664. X                total -= (long) (p->n_vsize * sizeof(LVAL));
  2665. X                free(p->n_vdata);
  2666. X            }
  2667. X            break;
  2668. X        }
  2669. X        p->n_type = FREE;
  2670. X        rplaca(p,NIL);
  2671. X        rplacd(p,fnodes);
  2672. X        fnodes = p;
  2673. X        nfree += 1L;
  2674. X        }
  2675. X        }
  2676. X    }
  2677. X}
  2678. X
  2679. X/* addseg - add a segment to the available memory */
  2680. XLOCAL int addseg()
  2681. X{
  2682. X    SEGMENT *newseg;
  2683. X    LVAL p;
  2684. X    int n;
  2685. X
  2686. X    /* allocate the new segment */
  2687. X    if (anodes == 0 || (newseg = newsegment(anodes)) == NULL)
  2688. X    return (FALSE);
  2689. X
  2690. X    /* add each new node to the free list */
  2691. X    p = &newseg->sg_nodes[0];
  2692. X    for (n = anodes; --n >= 0; ++p) {
  2693. X    rplacd(p,fnodes);
  2694. X    fnodes = p;
  2695. X    }
  2696. X
  2697. X    /* return successfully */
  2698. X    return (TRUE);
  2699. X}
  2700. X
  2701. X/* newsegment - create a new segment (only called here and in xlimage.c) */
  2702. XSEGMENT *newsegment(n)
  2703. X  int n;
  2704. X{
  2705. X    SEGMENT *newseg;
  2706. X
  2707. X    /* allocate the new segment */
  2708. X    if ((newseg = (SEGMENT *)calloc(1,segsize(n))) == NULL)
  2709. X    return (NULL);
  2710. X
  2711. X    /* initialize the new segment */
  2712. X    newseg->sg_size = n;
  2713. X    newseg->sg_next = NULL;
  2714. X    if (segs)
  2715. X    lastseg->sg_next = newseg;
  2716. X    else
  2717. X    segs = newseg;
  2718. X    lastseg = newseg;
  2719. X
  2720. X    /* update the statistics */
  2721. X    total += (long)segsize(n);
  2722. X    nnodes += (long)n;
  2723. X    nfree += (long)n;
  2724. X    ++nsegs;
  2725. X
  2726. X    /* return the new segment */
  2727. X    return (newseg);
  2728. X}
  2729. X/* stats - print memory statistics */
  2730. XLOCAL stats()
  2731. X{
  2732. X    sprintf(buf,"Nodes:       %ld\n",nnodes); stdputstr(buf);
  2733. X    sprintf(buf,"Free nodes:  %ld\n",nfree);  stdputstr(buf);
  2734. X    sprintf(buf,"Segments:    %d\n",nsegs);   stdputstr(buf);
  2735. X    sprintf(buf,"Allocate:    %d\n",anodes);  stdputstr(buf);
  2736. X    sprintf(buf,"Total:       %ld\n",total);  stdputstr(buf);
  2737. X    sprintf(buf,"Collections: %d\n",gccalls); stdputstr(buf);
  2738. X}
  2739. X
  2740. X/* xgc - xlisp function to force garbage collection */
  2741. XLVAL xgc()
  2742. X{
  2743. X    /* make sure there aren't any arguments */
  2744. X    xllastarg();
  2745. X
  2746. X    /* garbage collect */
  2747. X    gc();
  2748. X
  2749. X    /* return nil */
  2750. X    return (NIL);
  2751. X}
  2752. X
  2753. X/* xexpand - xlisp function to force memory expansion */
  2754. XLVAL xexpand()
  2755. X{
  2756. X    LVAL num;
  2757. X    int n,i;
  2758. X
  2759. X    /* get the new number to allocate */
  2760. X    if (moreargs()) {
  2761. X    num = xlgafixnum();
  2762. X    n = getfixnum(num);
  2763. X    }
  2764. X    else
  2765. X    n = 1;
  2766. X    xllastarg();
  2767. X
  2768. X    /* allocate more segments */
  2769. X    for (i = 0; i < n; i++)
  2770. X    if (!addseg())
  2771. X        break;
  2772. X
  2773. X    /* return the number of segments added */
  2774. X    return (cvfixnum((FIXTYPE)i));
  2775. X}
  2776. X
  2777. X/* xalloc - xlisp function to set the number of nodes to allocate */
  2778. XLVAL xalloc()
  2779. X{
  2780. X    int n,oldn;
  2781. X    LVAL num;
  2782. X
  2783. X    /* get the new number to allocate */
  2784. X    num = xlgafixnum();
  2785. X    n = getfixnum(num);
  2786. X
  2787. X    /* make sure there aren't any more arguments */
  2788. X    xllastarg();
  2789. X
  2790. X    /* set the new number of nodes to allocate */
  2791. X    oldn = anodes;
  2792. X    anodes = n;
  2793. X
  2794. X    /* return the old number */
  2795. X    return (cvfixnum((FIXTYPE)oldn));
  2796. X}
  2797. X
  2798. X/* xmem - xlisp function to print memory statistics */
  2799. XLVAL xmem()
  2800. X{
  2801. X    /* allow one argument for compatiblity with common lisp */
  2802. X    if (moreargs()) xlgetarg();
  2803. X    xllastarg();
  2804. X
  2805. X    /* print the statistics */
  2806. X    stats();
  2807. X
  2808. X    /* return nil */
  2809. X    return (NIL);
  2810. X}
  2811. X
  2812. X#ifdef SAVERESTORE
  2813. X/* xsave - save the memory image */
  2814. XLVAL xsave()
  2815. X{
  2816. X    unsigned char *name;
  2817. X
  2818. X    /* get the file name, verbose flag and print flag */
  2819. X    name = getstring(xlgetfname());
  2820. X    xllastarg();
  2821. X
  2822. X    /* save the memory image */
  2823. X    return (xlisave(name) ? true : NIL);
  2824. X}
  2825. X
  2826. X/* xrestore - restore a saved memory image */
  2827. XLVAL xrestore()
  2828. X{
  2829. X    extern jmp_buf top_level;
  2830. X    unsigned char *name;
  2831. X
  2832. X    /* get the file name, verbose flag and print flag */
  2833. X    name = getstring(xlgetfname());
  2834. X    xllastarg();
  2835. X
  2836. X    /* restore the saved memory image */
  2837. X    if (!xlirestore(name))
  2838. X    return (NIL);
  2839. X
  2840. X    /* return directly to the top level */
  2841. X    stdputstr("[ returning to the top level ]\n");
  2842. X    xllongjmp(top_level,1);
  2843. X}
  2844. X#endif
  2845. X
  2846. X/* xlminit - initialize the dynamic memory module */
  2847. Xxlminit()
  2848. X{
  2849. X    LVAL p;
  2850. X    int i;
  2851. X
  2852. X    /* initialize our internal variables */
  2853. X    segs = lastseg = NULL;
  2854. X    nnodes = nfree = total = 0L;
  2855. X    nsegs = gccalls = 0;
  2856. X    anodes = NNODES;
  2857. X    fnodes = NIL;
  2858. X
  2859. X    /* Since newvector etc depend on NULL==0, */  /* JSP */
  2860. X    /* do a quick check:                      */  /* JSP */
  2861. X    {                          /* JSP */
  2862. X        LVAL*v = (LVAL*)calloc(sizeof(LVAL),1);   /* JSP */
  2863. X        if (*v != NULL) xlfatal("NULL != 0");     /* JSP */
  2864. X        free(v);                  /* JSP */
  2865. X    }                          /* JSP */
  2866. X
  2867. X    /* allocate the fixnum segment */
  2868. X    if ((fixseg = newsegment(SFIXSIZE)) == NULL)
  2869. X    xlfatal("insufficient memory");
  2870. X
  2871. X    /* initialize the fixnum segment */
  2872. X    p = &fixseg->sg_nodes[0];
  2873. X    for (i = SFIXMIN; i <= SFIXMAX; ++i) {
  2874. X    p->n_type = FIXNUM;
  2875. X    p->n_fixnum = i;
  2876. X    ++p;
  2877. X    }
  2878. X
  2879. X    /* allocate the character segment */
  2880. X    if ((charseg = newsegment(CHARSIZE)) == NULL)
  2881. X    xlfatal("insufficient memory");
  2882. X
  2883. X    /* initialize the character segment */
  2884. X    p = &charseg->sg_nodes[0];
  2885. X    for (i = CHARMIN; i <= CHARMAX; ++i) {
  2886. X    p->n_type = CHAR;
  2887. X    p->n_chcode = i;
  2888. X    ++p;
  2889. X    }
  2890. X
  2891. X    /* initialize structures that are marked by the collector */
  2892. X    obarray = xlenv = xlfenv = xldenv = NIL;
  2893. X    s_gcflag = s_gchook = NIL;
  2894. X
  2895. X/* Include hybrid-class functions: *//* JSP */
  2896. X#define MODULE_XLDMEM_C_XLMINIT
  2897. X#include "../../xmodules.h"
  2898. X#undef MODULE_XLDMEM_C_XLMINIT
  2899. X
  2900. X    /* allocate the evaluation stack */
  2901. X    if ((xlstkbase = (LVAL **)malloc(EDEPTH * sizeof(LVAL *))) == NULL)
  2902. X    xlfatal("insufficient memory");
  2903. X    xlstack = xlstktop = xlstkbase + EDEPTH;
  2904. X
  2905. X    /* allocate the argument stack */
  2906. X    if ((xlargstkbase = (LVAL *)malloc(ADEPTH * sizeof(LVAL))) == NULL)
  2907. X    xlfatal("insufficient memory");
  2908. X    xlargstktop = xlargstkbase + ADEPTH;
  2909. X    xlfp = xlsp = xlargstkbase;
  2910. X    *xlsp++ = NIL;
  2911. X}
  2912. X
  2913. END_OF_FILE
  2914. if test 18074 -ne `wc -c <'src/xlisp/xcore/c/xldmem.c'`; then
  2915.     echo shar: \"'src/xlisp/xcore/c/xldmem.c'\" unpacked with wrong size!
  2916. fi
  2917. # end of 'src/xlisp/xcore/c/xldmem.c'
  2918. fi
  2919. echo shar: End of archive 8 \(of 16\).
  2920. cp /dev/null ark8isdone
  2921. MISSING=""
  2922. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2923.     if test ! -f ark${I}isdone ; then
  2924.     MISSING="${MISSING} ${I}"
  2925.     fi
  2926. done
  2927. if test "${MISSING}" = "" ; then
  2928.     echo You have unpacked all 16 archives.
  2929.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2930. else
  2931.     echo You still need to unpack the following archives:
  2932.     echo "        " ${MISSING}
  2933. fi
  2934. ##  End of shell archive.
  2935. exit 0
  2936.